GNU/Linux >> Linux Esercitazione >  >> Linux

Stampa le linee tra il motivo iniziale e quello finale, ma se il motivo finale non esiste, non stampare

Puoi farlo come segue:

$ sed -e '
    /BEGIN/,/END/!d
    H;/BEGIN/h;/END/!d;g
' inp

Il modo in cui funziona è che per l'intervallo di linee di inizio/fine le memorizza nello spazio di attesa. Quindi elimina finché non incontri la riga END. A quel punto ricordiamo ciò che è in attesa. OTW, non otteniamo nulla.HTH.


cat input |
sed '/\*\*\*\*\* BEGIN \*\*\*\*\*/,/\*\*\*\*\* END *\*\*\*\*/ p;d' | 
tac |
sed '/\*\*\*\*\* END \*\*\*\*\*/,/\*\*\*\*\* BEGIN *\*\*\*\*/ p;d' |
tac

Funziona avendo tac invertire le righe in modo che sed può trovare entrambi i delimitatori in entrambi gli ordini.


Con pcregrep :

pcregrep -M '(?s)BEGIN.*?END'

Funziona anche se BEGIN e END sono sulla stessa riga, ma non in casi come:

BEGIN 1 END foo BEGIN 2
END

Dove pcregrep cattura il primo BEGIN 1 END , ma non il secondo.

Per gestirli, con awk , potresti fare:

awk '
  !inside {
    if (match($0, /^.*BEGIN/)) {
      inside = 1
      remembered = substr($0, 1, RLENGTH)
      $0 = substr($0, RLENGTH + 1)
    } else next
  }
  {
    if (match($0, /^.*END/)) {
      print remembered $0
      if (substr($0, RLENGTH+1) ~ /BEGIN/)
        remembered = ""
      else
        inside = 0
    } else
      remembered = remembered $0 ORS
  }'

Su un input come:

a
BEGIN blah END BEGIN 1
2
END
b
BEGIN foo END
c
BEGIN
bar
END BEGIN
baz END
d
BEGIN
xxx

Dà:

BEGIN blah END BEGIN 1
2
END
BEGIN foo END
BEGIN
bar
END BEGIN
baz END

Entrambi devono memorizzare tutto dall'inizio alla fine successiva in memoria. Quindi, se hai un file enorme la cui prima riga contiene BEGIN ma senza END, l'intero file verrà archiviato in memoria per niente.

L'unico modo per aggirare il problema sarebbe elaborare il file due volte, ma ovviamente ciò potrebbe essere fatto solo quando l'input è un file normale (non una pipe per esempio).


Linux
  1. Perché l'espressione regolare funziona in X ma non in Y?

  2. open() in Python non crea un file se non esiste

  3. Aggiunta di una riga a un file solo se non esiste già

  4. Perché Tomcat funziona con la porta 8080 ma non con la 80?

  5. Il punto di montaggio non esiste, nonostante lo abbia creato

Linux – /sbin/init non esiste?

wc -l NON conta l'ultimo del file se non ha il carattere di fine riga

docker images mostra l'immagine, docker rmi dice che tale immagine o riferimento non esiste

La corrispondenza del modello non funziona nello script bash

Linee grep che iniziano con 1, ma non 10, 11, 100 ecc

Rimuovi i file che iniziano con ma non contengono