Come stampare una riga se quella riga o la riga successiva non contengono una stringa particolare


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

Uscita desiderata:

    8B0F
    8AC0
    8AE4
    8AE5

Voglio stampare una riga se quella riga o la riga successiva non contiene "rimuovi". Sto usando Solaris 5.10, KSH.


@don_crissti Grazie, posso contrassegnare questa domanda come risposta se pubblichi la tua risposta invece di commentare.
ayrton_senna,

Risposte:


14

Con sed:

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

Questo tira la Nlinea ext nello spazio del pattern (se non !sulla $linea del t) e controlla se lo spazio del pattern corrisponde remove. In caso contrario (significa che nessuna delle due righe nello spazio del motivo contiene la stringa remove) si Psfalda fino al primo \ncarattere di ewline (ovvero stampa la prima riga). Quindi si Delimina fino al primo \ncarattere di ewline e riavvia il ciclo. In questo modo, non ci sono mai più di due linee nello spazio del motivo.


E 'probabilmente più facile comprendere il N, P, Dciclo se si aggiunge lprima e dopo la Ndi guardare il pattern space:

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

quindi, usando solo le ultime sei righe del tuo esempio:

    8AC3
    remove
    8AE4
    8AE5
    8AE6
    remove

l'ultimo comando genera:

    8AC3 $
    8AC3 \ n rimuove $
    remove $
    rimuovi \ n 8AE4 $
    8AE4 $
    8AE4 \ n 8AE5 $
    8AE4
    8AE5 $
    8AE5 \ n 8AE6 $
    8AE5
    8AE6 $
    8AE6 \ n rimuove $
    remove $
    remove $

Ecco una breve spiegazione:

cmd output 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)

5
awk '
    !/remove/ && NR > 1 && prev !~ /remove/ {print prev} 
    {prev = $0} 
    END {if (!/remove/) print}
' Input.txt 

2
gawk 'BEGIN{ RS="remove\n"; ORS="" }
      RT{ print gensub("[^\n]*\n$","","") }; !RT{ print }' file

Il metodo sopra non legge i record riga per riga , ma legge i record su più righe da un Record Separator (RS) al successivo (o alla fine del file) - RSessendo la stessa riga "rimuovi" (incluso il suo finale "\ n).

Il !RTtest è necessario per quando l'ultima riga non è una RSriga.
RT, un gawk-ism , è il testo reale del record corrente RS.
gensubè anche un gawk-ism .

Se devi verificare la presenza di una linea di marcatura che corrisponde a "rimuovi" in qualsiasi punto della linea, rispetto a una linea che equivale a "rimuovi", modifica semplicemente il separatore record in:

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

Produzione:

8B0F
8AC0
8AE4
8AE5
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.