Posso grep solo le prime n righe di un file?


126

Ho file di log molto lunghi, è possibile chiedere a grep di cercare solo le prime 10 righe?

Risposte:


175

La magia delle pipe;

head -10 log.txt | grep <whatever>

13
puoi anche indirizzare un flusso arbitrario a head:someCmd | head -10
Stuart Nelson

1
Il valore predefinito di Head è la stampa delle prime 10 righe sullo standard output, quindi questo è valido per 10 righehead log.txt | grep <whatever>
Zlemini

5
C'è un modo per farlo quando si usa l' -lopzione di grep ? Vorrei elencare tutti i file che sono i primi 5 caratteri RIFFD.
James M. Lay,

49

Per le persone che lo trovano su Google, avevo bisogno di cercare le prime nrighe di più file, ma per stampare solo i nomi di file corrispondenti. ero solito

 gawk 'FNR>10 {nextfile} /pattern/ { print FILENAME ; nextfile }' filenames

L' FNR..nextfileinterrompe l'elaborazione di un file una volta che sono state visualizzate 10 righe. Il //..{}stampa il nome del file e va avanti ogni volta che viene visualizzata la prima corrispondenza in un dato file. Per citare i nomi dei file a vantaggio di altri programmi, utilizzare

 gawk 'FNR>10 {nextfile} /pattern/ { print "\"" FILENAME "\"" ; nextfile }' filenames

9
Ero una di quelle persone che l'hanno trovato su Google. Grazie!
Floris

per me, questo codice ha stampato il percorso completo del file. Che è esattamente ciò di cui avevo bisogno. Inoltre FNR=1cercherà solo la prima riga. Grazie!
Brian W

2
Per farlo in modo ricorsivo su una directory:find ./path -type -f -exec awk 'FNR>10 {nextfile} /pattern/ { print FILENAME ; nextfile }' '{}' +
OrangeDog

1
Grazie @OrangeDog. Una leggera correzione: dovrebbe essere-type f
David Siegal

26

Oppure utilizzare awkper un singolo processo senza |:

awk '/your_regexp/ && NR < 11' INPUTFILE

Su ogni riga, se your_regexpcorrisponde e il numero di record (righe) è inferiore a 11, esegue l'azione predefinita (che è stampare la riga di input).

Oppure usa sed:

sed -n '/your_regexp/p;10q' INPUTFILE 

Controlla la tua regexp e stampa la riga ( -nsignifica non stampare l'input, che è altrimenti l'impostazione predefinita), e si chiude subito dopo la decima riga.


1
Perché non smettere il 10? (vedi soluzione sed)
potong

awk '{ if ( NR <= 10 ) { if(index($0,"ab") > 0) { print $0; } } else { exit; } }' textfile-- Più veloce.

1
@potong hai ragione, corretto. @srikanthradix anche se può essere più veloce, la tua soluzione non è cercare espressioni regolari ma solo stringhe fisse. awk '{ if ( NR <= 10 ) { if( $0 ~ "YOUR_REGEXP") { print } } else { exit; } }' textfilelo fa.
Zsolt Botykai

4
Inoltre lo stile no awkish. 2xifse 1xelsein un comando che non necessita di alcuna dichiarazione di azione farebbe aho. weinberger e kernighan piangono ...
jaypal singh

1
Penso che invece di NR sarebbe meglio usare FNR, perché se usi awk con più file FNR parte da 0 per ogni file.
Vladyslav Savchenko

9

Hai alcune opzioni che utilizzano programmi insieme a grep. Il più semplice secondo me è usare head:

head -n10 filename | grep ...

headprodurrà le prime 10 righe (usando l' -nopzione), quindi puoi reindirizzare quell'output a grep.


6
Non me ne rendevo nemmeno conto, tutte le soluzioni qui usate headhanno utilizzato -n 10 (me compreso) non rendendomi conto che headdi default visualizza solo 10 righe . :)
jaypal singh



3

L'output di head -10 filepuò essere reindirizzato per ottenere grepciò:

head -10 file | grep 

Utilizzando Perl:

perl -ne 'last if $. > 10; print if /pattern/' file

3
head -10 log.txt | grep -A 2 -B 2 pattern_to_search

-A 2: stampa due righe prima del motivo.

-B 2: stampa due righe dopo il motivo.

head -10 log.txt # read the first 10 lines of the file.

1
Se ricordo bene, -C 2farà lo stesso di-A 2 -B 2
David LeBauer il

3
grep -m6 "string" cov.txt

Questo cerca solo le prime 6 righe per string


3
No, questo ti darà le prime 6 occorrenze di "stringa" nell'intero file cov.txt
franzisk

2

Un'estensione alla risposta di Joachim Isaksson: molto spesso ho bisogno di qualcosa dalla metà di un file lungo, ad esempio le righe da 5001 a 5020, nel qual caso puoi combinare headcon tail:

head -5020 file.txt | tail -20 | grep x

Questo ottiene le prime 5020 righe, quindi mostra solo le ultime 20 di quelle, quindi convoglia tutto in grep.

(Modificato: errore fencepost nei miei numeri di esempio, aggiunta pipe a grep)


1

grep -A 10 <Pattern>

Questo per afferrare il modello e le successive 10 linee dopo il modello. Questo funzionerebbe bene solo per un pattern noto, se non si dispone di un pattern noto utilizzare i suggerimenti "head".


1
Anche se potrebbe essere giusto. aggiungere più descrizione della domanda per rendere la risposta più completa.
Pramod S. Nikam

3
Questo risponde a una domanda completamente diversa e non è utile in questo contesto.
Pre101

-1

Ho avuto un problema simile e tutto il problema di cui sopra non lo risolve del tutto. Sono anche interessato a ottenere il nome del file contenente le righe corrispondenti. La mia soluzione:

ls |parallel --gnu 'cat <(echo {}) <(head {})|grep -B1 -m1 -P "^>.*F3$"'

NB: Il Pattern nel mio caso corrisponde sempre alla prima riga.

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.