2012-11-23 7 views
27

Con grep, so come impostare il contesto su un numero fisso di linee. È possibile mostrare un contesto basato su una condizione di stringa arbitraria, come impostare after-context su "until the blank line"?Come posso impostare grep dopo che il contesto è "fino alla prossima riga vuota"?

O forse qualche altra combinazione di strumenti?

Fondamentalmente ho un file di log di linee contigue, con righe vuote che separano gli "eventi" Voglio cercare una stringa nel file di registro, ma mostrano l'intero evento ....

+0

Ciò è possibile con altri strumenti. Se pubblichi un esempio, otterrai risposte specifiche. –

+0

Probabilmente vuoi usare 'sed' o' awk' per quello ... – dmckee

+0

Come posso fare inverso di questo. Ho un file di registro con stack di chiamate. Non voglio stampare uno stack di chiamate ma voglio tutti gli altri stack di chiamate – Nikole

risposta

24

Suona come è necessario sed:

sed -n '/pattern/,/^$/p' file 

non stampare per default (-n). Per righe corrispondenti a /pattern/ fino a una riga vuota /^$/, stampare.

+0

Nota che questo non mostra l'intero evento, ma manca quelle linee dell'evento che precede il modello. –

+2

Per clearify: il comando è del formato '', ''. Trova intervalli di indirizzi compresi (intervalli di righe) che iniziano con una corrispondenza di 'pattern' e che terminano con una corrispondenza di una riga vuota successiva (corrispondente a'^$ '). Per ogni gamma viene eseguita la funzione ('p': stampa linee in entrata). Per escludere le righe vuote dall'output usare 'sed -n '/ pattern /,/^ $/{/^$ /! P}' file'. Qui '/^$ /! P' significa stampare qualsiasi riga in entrata che non corrisponda a'^$ '. – valid

+1

Questo ha funzionato perfettamente per me, con un'eccezione: il mio input sorgente aveva newline in stile DOS (\ r \ n), quindi dovevo farlo invece: 'sed -n '/ pattern /,/^ \ r $/p 'file' – bmaupin

7

Ecco un (testato) awk soluzione, separati su più righe per migliorare la leggibilità:

awk '/pattern/ {do_print=1} 
    do_print==1 {print} 
    NF==0 {do_print=0}' input_file 

Questo script stampa anche la linea in bianco in modo che sia più facile per separare visivamente i diversi blocchi abbinati. Se non si desidera che la riga vuota, scambiare le 2 linee do_print==1 {print} e NF==0 {do_print=0}

Spiegazione:

  • awk: richiamare lo strumento awk - valuta l'una linea di ingresso alla volta in sequenza.
  • '...'.: tutto racchiuso tra virgolette singole viene dato a awk come istruzioni. In questo caso, eseguiamo le istruzioni quotate su ogni riga.
  • /pattern/ {do_print=1}: ogni volta che una riga contiene "pattern", accendere la do_print bandiera
  • do_print==1 {print}: se il flag do_print è attivata, stampare la riga corrente.
  • NF==0 {do_print=0}: NF sta per Numero di campi. awk delimita ogni riga in base a spazi e tabulazioni per impostazione predefinita per suddividere una riga in campi. In questo caso banalmente una riga vuota non ha campi - quindi abbiamo spegnere la bandiera do_print per fermare la stampa quando vediamo una linea con NF == 0
18

Una soluzione semplice è:

awk '/pattern/' RS= input-file 

Impostazione RS al stringa vuota fa awk trattare le righe vuote come separatore dei record, e la semplice regola /pattern/ fa in modo che awk stampi qualsiasi record che corrisponda al modello, che può essere qualsiasi espressione regolare estesa.

Problemi correlati