grep un file, ma mostra diverse linee circostanti?


3420

Vorrei grepuna stringa, ma mostra anche le cinque righe precedenti e le cinque righe seguenti, nonché la riga corrispondente. Come potrei farlo?


3
Tengo una copia della sceneggiatura di Perl di Brendan Gregg in giro per questo scopo. Funziona bene.
Ethan Post,

6
Per una soluzione che funziona su Solaris, consulta questo link .
jahroy,

107
man grep | grep -C 1 context:)
StvnW,

20
man grep | grep -C 1 "\-C";)
Anders B

9
@StvnW ... Non so se chiamare quel meta (in un contesto più generale, piuttosto che SO), o come chiamarlo. Hai risposto alla domanda mostrando come utilizzare la risposta per trovare la risposta.
bballdave025

Risposte:


4539

Per BSD o GNU grep puoi usare -B numper impostare quante linee prima della partita e -A numper il numero di linee dopo la partita.

grep -B 3 -A 2 foo README.txt

Se vuoi lo stesso numero di righe prima e dopo puoi usarlo -C num.

grep -C 3 foo README.txt

Questo mostrerà 3 righe prima e 3 righe dopo.


56
È buono ma sfortunatamente il grep di Solaris non lo supporta. Vedi quel link per solaris: unix.com/solaris/33533-grep-display-few-lines-before-after.html
рüффп

9
Ok, ma cosa succede se vuoi mostrare tutte le righe di output dopo la partita? grep -A0 e grep -A-1 non tagliarlo ...
g33kz0r

2
non funziona per me per qualche motivo, anche se menzionato nelle mie pagine man.
Hayri Uğur Koltuk,

2
Se si è HP-UX env, nessuna delle versioni grep funzionerà come in Solaris. È stato in grado di utilizzare il collegamento Solaris ma sostituire nawk con awk in quel collegamento.
zkarthik,

6
-n è per i numeri di riga, ma per alcune versioni di grep -n # mostrerà # righe circostanti (come -c) con i numeri di riga. Questa è una scorciatoia utile che è la mia scelta quando ho bisogno di un contesto.
Anthony DiSanti,

607

-Ae -Bfunzionerà, come -C n(per le nlinee di contesto), o semplicemente -n(per le nlinee di contesto ... fintanto che n è da 1 a 9).


Ho provato il -nformato e ho scoperto che funziona solo fino a 9. Perché 15restituisce 5 righe
Deepak Mahakale il

8
@DeepakMahakale Probabilmente è correlato al modo in cui gli argomenti / opzioni della riga di comando vengono in genere analizzati dai programmi POSIX. L'identificatore di opzione è un singolo carattere (come -A, -Bo -C). Di solito, l'identificatore di opzione è seguito da un valore ( -o a.outper specificare il file di output in GCC), ma può anche funzionare come un semplice switch / flag ( -gper abilitare le informazioni di debug in GCC). Tuttavia, gli spazi tra le opzioni sono facoltativi, quindi per le opzioni senza un valore è possibile unirle ( -ABC), il che significa che -15viene interpretato -1 -5(due opzioni separate) e -5sostituisce il -1.
natiiix,

1
-5 è più veloce di entrambi -A 5 -B 5. Questi non devono essere usati insieme. È più pulito per gli altri lettori della sceneggiatura se si sceglie -A o -B o -C su -9.
Eric Aldinger,

77

ack funziona con argomenti simili a grep e accetta -C. Ma di solito è meglio per la ricerca attraverso il codice.


5
ack supporta anche -A -B.
Shuo,

Ack è meglio di grep in molti modi. È più veloce con una sintassi più semplice.
Chim

1
grep ha il vantaggio di essere installato di default su molti sistemi.
Marc Z,

1
@MarcZ: True, è più probabile che grep sia installato per impostazione predefinita rispetto a ack, ma ack è uno script portatile e autonomo. Non è necessario compilarlo o installarlo in una directory di sistema come / usr / bin /. Una volta scaricato e inserito in una directory elencata in $ PATH (e il suo bit di autorizzazione eXecute impostato), dovrebbe funzionare immediatamente. (Non sono richiesti privilegi sudo o root per far funzionare il software.)
JL

Questa domanda riguarda grep: non è sicuro usarla per "pubblicizzare" ack(che è davvero un ottimo strumento) è una buona idea ...
MonsieurDart

39
grep astring myfile -A 5 -B 5

Questo farà "myfile" per "astring" e mostrerà 5 righe prima e dopo ogni incontro


19
"grep astring myfile -C 5" farà lo stesso
Syed Siraj Uddin,

20

Io normalmente uso

grep searchstring file -C n # n for number of lines of context up and down

Molti strumenti come grep hanno anche file man davvero fantastici. Mi trovo a riferirmi molto alla pagina man di grep perché c'è così tanto che puoi farci.

man grep

Molti strumenti GNU hanno anche una pagina informativa che può contenere informazioni più utili oltre alla pagina man.

info grep

13

Usa grep

$ grep --help | grep -i context
Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context=NUM         print NUM lines of output context
  -NUM                      same as --context=NUM

Non hai letto la risposta accettata? Stai solo ripetendo quello che è già stato detto su una domanda di quasi 10 anni ...
Yokai

7
Oh mi dispiace Yokai. Ma non leggo nulla sul grepping nella sezione di aiuto di grep per recuperare la risposta.
Chiel dieci Brinke,

1
@Yokai Oltre a ciò che ha detto Chiel ten Brinke, la risposta accettata non menziona le opzioni lunghe
user3738870

11

Cerca "17655" in "/some/file.txt" che mostra il contesto di 10 righe prima e dopo (usando Awk), l'output è preceduto dal numero di riga seguito da due punti. Usalo su Solaris quando 'grep' non supporta le opzioni "- [ACB]".

awk '

/17655/ {
        for (i = (b + 1) % 10; i != b; i = (i + 1) % 10) {
                print before[i]
        }
        print (NR ":" ($0))
        a = 10
}

a-- > 0 {
        print (NR ":" ($0))
}

{
        before[b] = (NR ":" ($0))
        b = (b + 1) % 10
}' /some/file.txt;

7

ripgrep

Se ti preoccupi delle prestazioni, usa ripgrepuna sintassi simile a grep, ad es

rg -C5 "pattern" .

-C, --context NUM- Mostra NUM righe prima e dopo ogni corrispondenza.

Ci sono anche parametri come -A/ --after-contexte -B/ --before-context.

Lo strumento è basato sul motore regex di Rust che lo rende molto efficiente per i dati di grandi dimensioni.


5

Ecco la soluzione @Ygor inawk

awk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=3 a=3 s="pattern" myfile

Nota: Sostituisci ae bvariabili con il numero di righe prima e dopo.

E 'particolarmente utile per il sistema che non supporta di grep -A, -Be -Cparametri.


4
$ grep thestring thefile -5

-5ti mette le 5righe sopra e sotto la corrispondenza 'thestring' equivale a -C 5o -A 5 -B 5.


4

Grep ha un'opzione chiamata Context Line Control, puoi usare --contextquella semplicemente,

| grep -C 5

o

| grep -5

Dovrebbe fare il trucco


1

Uso per fare in modo compatto

grep -5 string file

Questo è l'equivalente di

grep -A 5 -B 5 string file

0

Se cerchi spesso il codice, AG cerca argento è molto più efficiente (cioè più veloce) di grep.

Mostra le linee di contesto usando l'opzione -C.

Per esempio:

ag -C 3 "foo" myFile

line 1
line 2
line 3
line that has "foo"
line 5
line 6
line 7
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.