Cómo imprimir una línea si esa línea o la siguiente no contienen una cadena particular

8

Input.txt:

    8B0C
    remove
    8B0D
    remove
    8B0E
    remove
    8B0F
    8B10
    remove
    8B14
    remove
    8B15
    remove
    8B16
    remove
    8B17
    remove
    8AC0
    8AC1
    remove
    8AC2
    remove
    8AC3
    remove
    8AE4
    8AE5
    8AE6
    remove

Salida deseada:

    8B0F
    8AC0
    8AE4
    8AE5

Quiero imprimir una línea si esa línea o la siguiente línea no contiene 'eliminar'. Estoy usando solaris 5.10, KSH.

Ayrton Senna
fuente
@don_crissti Gracias, puedo marcar esta pregunta como respondida si publicas tu respuesta en lugar de comentar.
ayrton_senna

Respuestas:

14

Con sed:

sed '$!N;/remove/!P;D' infile

Esto tira de la Nlínea ext al espacio del patrón (si no está !en la $línea t) y verifica si el espacio del patrón coincide remove. Si no lo hace (significa que ninguna de las dos líneas en el espacio del patrón contiene la cadena remove), se Palinea con el primer \ncarácter de línea ew (es decir, imprime la primera línea). Luego Delige hasta el primer \ncarácter ewline y reinicia el ciclo. De esta manera, nunca hay más de dos líneas en el espacio del patrón.


Es probable que sea más fácil de entender el N, P, Dciclo si se agrega lantes y después de la Nque mirar el espacio de patrones:

sed 'l;$!N;l;/remove/!P;D' infile

entonces, usando solo las últimas seis líneas de su ejemplo:

    8AC3
    remove
    8AE4
    8AE5
    8AE6
    remove

el último comando sale:

    8AC3 $
    8AC3 \ n eliminar $
    eliminar $
    eliminar \ n 8AE4 $
    8AE4 $
    8AE4 \ n 8AE5 $
    8AE4
    8AE5 $
    8AE5 \ n 8AE6 $
    8AE5
    8AE6 $
    8AE6 \ n eliminar $
    eliminar $
    eliminar $

Aquí hay una breve explicación:

cmd salida cmd
l     8AC3$                  N # read in the next line
l     8AC3\n    remove$      D # delete up to \n (pattern space matches so no P)
l     remove$                N # read in the next line
l     remove\n    8AE4$      D # delete up to \n (pattern space matches so no P)
l     8AE4$                  N # read in the next line
l     8AE4\n    8AE5$        # pattern space doesn't match so print up to \n
P     8AE4                   D # delete up to \n
l     8AE5$                  N # read in the next line
l     8AE5\n    8AE6$        # pattern space doesn't match so print up to \n
P     8AE5                   D # delete up to \n 
l     8AE6$                  N # read in the next line
l     8AE6\n    remove$      D # delete up to \n (pattern space matches so no P)
l     remove$                # last line so no N 
l     remove$                D # delete (pattern space matches so no P)
don_crissti
fuente
5
awk '
    !/remove/ && NR > 1 && prev !~ /remove/ {print prev} 
    {prev = $0} 
    END {if (!/remove/) print}
' Input.txt 
Glenn Jackman
fuente
2
gawk 'BEGIN{ RS="remove\n"; ORS="" }
      RT{ print gensub("[^\n]*\n$","","") }; !RT{ print }' file

El método anterior no lee los registros línea por línea , sino que lee los registros de varias líneas de un separador de registros (RS) al siguiente (o al final del archivo), RSsiendo la línea "eliminar" en sí (incluida su Trailing `\ n).

La !RTprueba es necesaria para cuando la última línea no es una RSlínea.
RT, un gawk-ism , es el texto real del registro actual RS.
gensubTambién es un gawk-ismo .

Si necesita verificar una línea de marcador que coincida con "eliminar" en cualquier parte de la línea, frente a una línea que equivale a "eliminar", simplemente cambie el Separador de registro a:

`RS="[^\n]*remove[^\n]*\n"`  

Salida:

8B0F
8AC0
8AE4
8AE5
Peter.O
fuente