it-swarm.it

Mostra tutti i file fino alla partita

grep --before-context 5 mostra 5 righe prima della partita.

Voglio mostrare tutto prima della partita.
Fare grep --before-context 99999999 funzionerebbe ma non è molto ... professionale.

Come mostrare tutti i file fino alla partita?

78
Nicolas Raoul

Sed è meglio per questo.

Basta fare:

sed '/PATTERN/q' FILE

Funziona così:

Per ogni riga, cerchiamo se corrisponde a /PATTERN:

  • se sì, lo stampiamo e usciamo
  • altrimenti, lo stampiamo

Questa è la soluzione più efficiente, perché non appena vede PATTERN, si chiude. Senza q, sed continuerebbe a leggere il resto del file e non farebbe nulla con esso. Per file di grandi dimensioni può fare la differenza.

Questo trucco può anche essere usato per emulare head:

sed 10q FILE
104
Mikel

sed può sostituire la maggior parte delle funzionalità di grep.

sed -n '1,/<pattern>/ p' <file>

Questo significa stampare dalla prima riga fino a quando il motivo non viene abbinato.

Un paio di esempi di gamma

sed -n '/<pattern>/,$ p' <file> # from pattern to end of file
sed -n '/<pattern1>/,/<pattern2>/ p' <file> # from pattern1 to pattern2
39
forcefsck

stampa fino alla partita inclusa:

awk '{print} /pattern/ {exit}' filename
sed '/pattern/q' filename

stampa fino a MA NON compresa la corrispondenza:

awk '/pattern/ {exit} {print}' filename
sed '/pattern/Q' filename
39
glenn jackman

Per le persone che scelgono di ricordare solo gli strumenti di base nel lavoro quotidiano e che desiderano accettare soluzioni meno eleganti e meno efficienti:

head -n $(grep -n pattern filename | cut -d: -f1) filename

Se questo comando è per uno script, cercherò soluzioni più eleganti (e possibilmente efficienti). Se questo è un comando una tantum o uno script usa e getta, non mi interessa.

1
lesmana

Aggiunta alla risposta di Mikel sopra ...


Per stampare tutte le righe fino a, ma senza includere , la prima riga in FILE contenente PATTERN, prova:

  • sed '/.*PATTERN.*/{s///;q;}' FILE

Questo corrisponde all'intera riga contenente il modello, lo sostituisce con una riga vuota, quindi si chiude senza elaborare il resto del file.


Post-script:

Il modo più semplice/chiaro a cui potevo pensare per evitare di stampare una nuova riga alla fine (senza coinvolgere un altro strumento), era di eseguire di nuovo sed ed eliminare la nuova riga finale:

sed '/.*PATTERN.*/{s///;q;}' FILE | sed '$d'

... e dal momento che stiamo eliminando comunque quella linea, il nostro lavoro precedente è ridondante e possiamo semplificare per:

sed '/PATTERN/q' FILE | sed '$d'
1
Jim Grisham

I seguenti metodi pure GNU grep non sono efficienti.

Cerca tutto fino alla prima istanza della stringa " foo " in file barra , usando tre greps:

grep -m 1 -B $(grep -n -m 1 foo bar | grep -o '^[0-9]*') foo bar

Corrispondenza fino all'ultima istanza di " foo ":

grep -oPz "(?s)[^\n]*${s}.*?\n.*?foo.*?\n" bar

Nota: i dettagli sull'ultimo grep sono disponibili in: Regex (grep) per la ricerca su più righe necessaria .

1
agc

È inoltre possibile utilizzare uno dei seguenti

tac ./test | grep -B $(cat ./test | wc -l) -m 1 'pattern'|tac 

o

tac ./test |head -n $(tac ./test | grep -n 'pattern' | cut -d: -f1 | head -n 1)|tac

o

tac ./test |sed ':a;N;$!ba;s/\n/'"pattern"'/g' | sed 's/'"patternpattern"'/\n/g'|head -n 1|sed 's/'"pattern"'/\n/g'|tac

La prima opzione è molto simile a quella suggerita dall'OP, ma assicura che ti mostri abbastanza righe prima del contesto contando le righe nel file

La seconda opzione cerca il numero di riga della prima corrispondenza (puoi cambiarlo anche cambiando la 'testa' interna) e quindi usa la testa su quel numero

L'ultima opzione sostituisce tutte le nuove linee con la corrispondenza e quindi sostituisce due partite adiacenti con una nuova linea. L'output di questo è una riga per ogni blocco di testo tra due corrispondenze. Dopodiché usa 'head' per scegliere la prima riga (che comprende il blocco di testo fino alla prima corrispondenza) e poi ritraduce ogni corrispondenza in una nuova riga. questa opzione funziona solo se il file è nel seguente formato

pattern
texttexttext
texttexttext texttexttext
texttexttexttexttexttexttexttexttext
pattern
texttexttext
pattern 
texttexttext
texttexttexttexttexttexttexttexttext

e così via

0
user122778