1 votos

Bash: ¿Eliminar las líneas del archivo de texto que comienzan después de una fila coincidente? (AppleScript ok)

Tengo estos archivos de texto horriblemente formateados que se ven así:

Heading
FIELD_DELIM TABS
VIDEO_FORMAT    1080
FILM_FORMAT 35mm, 4 perf
AUDIO_FORMAT    48khz
FPS 24

Column
Name    Tape    Start   Source File End Tc in   Tracks  

Data
WTF0567_comp_v446.15068     00:00:41:16 WTF0567_comp_v446.15068.mov 00:00:43:19 04:02:37:21 V   
OMG5120_fx_v001     00:00:42:11 OMG5120_fx_v001.mov 00:00:43:20 02:14:42:17 V   
NAW0366_anim_v032       00:00:41:16 GTP0170_MPC_comp_v0219.mov  00:00:44:21 01:02:20:05 V   

Sí, hay una pestaña horizontal vacía al final de algunas filas, pero no de otras. También hay una línea vacía en la parte inferior, que no sé cómo mostrar aquí en code formato.

SOLICITUD: Necesito eliminar todas las líneas debajo de la línea que comienza con "Datos" de estos archivos de texto. Me gustaría hacer esto como código bash, pero una solución AppleScript debería funcionar también. Puntos extra si podemos conservar esa última línea vacía.

3voto

thrig Puntos 101

Suponiendo que sus datos están en un archivo llamado input y que input es un archivo de texto unix ( \n para los finales de línea, no \r (Mac OS tradicional) ni los \r\n (avances en la línea de Internet)):

$ cat input
Heading
FIELD_DELIM TABS
VIDEO_FORMAT    1080
FILM_FORMAT 35mm, 4 perf
AUDIO_FORMAT    48khz
FPS 24

Column
Name    Tape    Start   Source File End Tc in   Tracks

Data
WTF0567_comp_v446.15068     00:00:41:16 WTF0567_comp_v446.15068.mov 00:00:43:19 04:02:37:21 V
OMG5120_fx_v001     00:00:42:11 OMG5120_fx_v001.mov 00:00:43:20 02:14:42:17 V
NAW0366_anim_v032       00:00:41:16 GTP0170_MPC_comp_v0219.mov  00:00:44:21 01:02:20:05 V

el sed puede imprimir líneas ( p ), pero dejará de hacerlo ( q ) al encontrar una línea que comienza con Data . Las pulsaciones de teclas eran bastante caras en los días del módem de 300 baudios, por eso los comandos de una sola letra.

$ sed -n '/^Data/q;p' input
Heading
FIELD_DELIM TABS
VIDEO_FORMAT    1080
FILM_FORMAT 35mm, 4 perf
AUDIO_FORMAT    48khz
FPS 24

Column
Name    Tape    Start   Source File End Tc in   Tracks

Para salir "después" del Data sólo hay que manipular un poco la lógica, o añadir un Data línea de nuevo utilizando un subshell para agrupar la salida con el sed comando:

sed '/^Data/q' input
( sed -n '/^Data/q;p' input; printf "Data\n" )

O bien, puede utilizar awk que aquí es más o menos lo mismo que el sed sólo que más verboso:

$ awk '/^Data/{exit} {print}' input
Heading
FIELD_DELIM TABS
VIDEO_FORMAT    1080
FILM_FORMAT 35mm, 4 perf
AUDIO_FORMAT    48khz
FPS 24

Column
Name    Tape    Start   Source File End Tc in   Tracks

awk probablemente hace más fácil forzar la inclusión de su última línea es requisito en blanco ( sed puede hacer esto pero es más molesto, o no, dependiendo de la versión exacta de sed implicados):

awk '/^Data/{print "this line left blank";exit} {print}'
awk '/^Data/{print "";exit} {print}'
awk '/^Data/{print;exit} {print}' input

También puede hacerlo en bash pero bash no es realmente una buena opción para esto en comparación con sed o awk o realmente cualquier otra cosa, y sería mucho más lento. Pero, ya que preguntaste...

while IFS= read -r line || [[ -n $line ]]; do [[ $line = Data* ]] && break; printf '%s\n' "$line"; done < input

Ver lo que quiero decir acerca de bash ? Vaya.

( sed y awk no son bash comandos; bash (1989) no existía cuando sed fue escrito (1974). bash puede ejecutar comandos unix, pero también cualquier otro shell unix, por ejemplo sh , ksh , zsh , fish , etc. y lo mismo puede hacer cualquier programa unix que haga un exec(3) a no ser que te refieras a bash en una especie de "¡esto es unix! Conozco unix!" en el sentido de (Jurrasic Park, 1993), como si "google" significara buscar, tal vez sin usar nada hecho por Google. Sólo uno de los comandos anteriores fue realmente ejecutado bajo bash por ejemplo).

1voto

Mockman Puntos 16

Aquí hay una solución de applescript. Lee el documento de texto, encuentra el desplazamiento del salto de línea y trunca en ese punto, haciendo que el salto de línea sea el último carácter del documento.

tell application "Finder" to set srcFile to choose file

-- read file and locate last desirable character position
set rFile to read srcFile
set dataOffset to (offset of "Data" & linefeed in rFile) + 4 -- will be linefeed
--> 171

-- end file at last desirable character
set eof of srcFile to dataOffset

read srcFile -- view results

1voto

Mockman Puntos 16

En cuanto a tomar una ruta basada en el shell estos tres enfoques buscan un rango que llega desde el principio del documento hasta la línea de 'Datos' y luego imprime eso mientras ignora cualquier texto posterior.

Los dos primeros funcionarán suponiendo que la primera línea empiece por "Título". Es probable que si se descubre una forma de especificar el primer carácter o palabra del documento, se pueda implementar en su lugar. Por defecto, todos parecen dejar una línea vacía al final del documento.

Primero, awk:

% awk '/^Heading/,/Data$/' blue.txt > green.txt

Entonces, perl:

% perl -ne 'print if /Heading/../Data$/' blue.txt > red.txt

Por último, sed:

% sed -n '1,/Data/ p' blue.txt > yellow.txt

Tenga en cuenta que el comando sed especifica la línea 1 en lugar de un texto concreto, por lo que funcionará incluso cuando su documento comience con algún otro texto. Debo añadir que estoy usando el sed por defecto que viene con Sierra. No parece haber una forma de obtener su versión, pero está en '/usr/bin/', así que es probable que sea original.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X