Domanda:
"Grep" che evidenzia invece di filtrare
ordago
2014-12-05 13:47:33 UTC
view on stackexchange narkive permalink

Mi chiedevo se esiste un programma nel set di strumenti unix comune come grep che invece di filtrare le righe che contengono una stringa, restituisce semplicemente lo stesso input ma evidenzia o colora la stringa selezionata.

Stavo pensando di farlo da solo (dovrebbe essere abbastanza semplice), ma forse esiste già come comando unix.

Sto pensando di usarlo per monitorare i log, quindi farei qualcosa del genere :

  tail -f logfile.log | evidenzia "errore"  

Di solito quando controllo i log ho bisogno di trovare una stringa particolare ma ho anche bisogno di sapere cosa c'è scritto prima e dopo la stringa, quindi filtrare a volte non è sufficiente .

Esiste qualcosa del genere?

Grazie

Praticamente risposto qui: http://stackoverflow.com/questions/981601/colorized-grep-viewing-the-entire-file-with-highlighted-matches
Questo mi sembra fuori tema, in quanto non richiede un'app. Sarebbe sicuramente meglio chiedere su https://unix.stackexchange.com/
Quattordici risposte:
fedorqui
2014-12-05 16:44:24 UTC
view on stackexchange narkive permalink

Questo è un trucco divertente con il comando di base grep . Consiste nell'utilizzo di due filtri: quello che si desidera applicare e uno fittizio che corrisponde a tutte le linee ma non produce evidenziazioni. Questa corrispondenza fittizia può essere ^ (inizio riga) o $ (fine riga).

  grep "^ \ | text "--color = file 'sempre'  

o

  grep -E" ^ | text "--color = file 'sempre'  

Guarda un esempio:

  $ cat ahello questo è del testo che volevo condividere con te $ grep "^ \ | text" --color = 'sempre' ahello questo è del testo che volevo # "testo" fosse evidenziato da condividere con te  
Sembra che tu non abbia nemmeno bisogno di "^" o "$" e anche solo "" | text "" funziona.
user450
2014-12-05 14:54:22 UTC
view on stackexchange narkive permalink

Esiste uno strumento chiamato ack . Puoi trovarlo su http://beyondgrep.com ed è davvero uno strumento oltre a grep. Il suo uso più comune è il riempimento del ruolo di find. -name "* .java" --print | xargs grep clazz o simili. Perché lo facciamo sempre.

Basta ack clazz e ottieni l'output. Cerca i file corretti (non si preoccupa di provare a grep i binari) e fornisce anche un buon risultato a colori.

Se lo usi con l'opzione --passthru stamperà il l'intero flusso di input, evidenziando le regioni corrispondenti a colori.

--passthru Stampa tutte le righe, che corrispondano o meno

Poiché la documentazione afferma che se - viene utilizzato per il file, ci vorrà STDIN:

Se vengono specificati file o directory, vengono controllati solo quei file e directory . ack può anche cercare STDIN, ma solo se non sono specificati argomenti di file o directory, o se uno di questi è "-".

Quindi, scusa il cat abuso ( e il gioco di parole - vedi sotto ) puoi averlo:

  $ cat file | ack - modello passante $ cat file | ack --passthru pattern -  

Questo prenderà l'output della pipe e lo invierà tramite ack che stamperà tutte le righe (con - -passthru ) con il pattern evidenziato.

Questo è esattamente lo strumento che stai cercando (e un po 'di più). È un pacchetto standard per molti gestori di pacchetti. Vedi http://beyondgrep.com/install/ per il tuo preferito.

 _ /|\'o.O'=(___)= U ack --thpppt! 

(Se non lo riconosci, questo è Bill the Cat anche se la ricerca di immagini potrebbe aiutare - non fare clic sul set di Miley Cyrus )

Ack è un ottimo strumento, ma come può stampare l'intero input semplicemente evidenziando lo schema di ricerca? Normalmente è usato come una forma di `grep -R` mirato come spieghi, non vedo come possa aiutare l'OP.
@terdon l'opzione `--passthru` stamperà tutte le linee ed evidenzierà gli schemi di interesse. Allo stesso modo, per lavorare su STDIN, è possibile utilizzare il trattino come "nome" del file o nessun argomento del file.
Capisco, ha senso. Dato che avevi detto che si comporta come grep, ho pensato che avrebbe stampato solo la riga corrispondente.
@terdon la sua modalità predefinita è grepy. Sebbene le persone abbiano sottolineato con altre opzioni, si può indurre grep a stampare tutte le righe ed evidenziare il testo di interesse. ack non ha bisogno di essere ingannato per farlo - è una delle opzioni standard. E grazie per la modifica chiarificatrice.
Steve Barnes
2014-12-05 14:04:50 UTC
view on stackexchange narkive permalink

Potresti usare il flag grep -C che fornisce n righe di contesto, ad es. grep -C 3 stamperà le 3 righe prima e dopo la corrispondenza. Ci sono anche -B e -A per prima e dopo.

Se stai cercando di evidenziare determinate stringhe regolarmente, ad es. formati di log specifici potrebbe valere la pena usare python pygmentize con un lexer personalizzato, poiché è basato su regex sarai stupito di quanto sia facile . Quest'ultimo ha anche il vantaggio di essere multipiattaforma sebbene alcuni terminali non colorino molto bene.

terdon
2014-12-06 18:17:12 UTC
view on stackexchange narkive permalink

Ho scritto un piccolo script che colorerà qualunque stringa tu gli dia:

  #! / usr / bin / env perluse Getopt :: Std; usa rigoroso; usa Term :: ANSIColor; my% opts; getopts ('hic: l:', \% opts); if ($ opts {h}) {print<<EoF; Usa -l per specificare i pattern da evidenziare. Per specificare più di un modello utilizzare le virgole. -l: un'espressione regolare Perl da colorare. Più espressioni possono essere passate come valori separati da virgole: -l pippo, bar, baz-i: fa distinzione tra maiuscole e minuscole-c: elenco di colori separato da virgole; EoF exit (0); } my $ case_sensitive = $ opts {i} || undef; my @color = ('bold red', 'bold blue', 'bold yellow', 'bold green', 'bold magenta', 'bold cyan', ' yellow on_magenta ',' bright_white on_red ',' bright_yellow on_red ',' white on_black '); if ($ opts {c}) {@ color = split (/, /, $ opts {c});} my @patterns; if ($ opts {l}) {@ patterns = split (/, /, $ opts {l});} else {$ patterns [0] = '\ *';} # Setting $ | a diverso da zero forza un flush subito e dopo ogni # scrittura o stampa sul canale di output attualmente selezionato. $ | = 1; while (my $ line = <>) {for (my $ c = 0; $ c< = $ # patterns; $ c ++) {if ($ case_sensitive) {if ($ line = ~ / $ patterns [$ c] /) {$ riga = ~ s / ($ pattern [$ c]) / color ("$ color [$ c]"). $ 1.color ("reset") / ge; }} else {if ($ riga = ~ / $ pattern [$ c] / i) {$ line = ~ s / ($ pattern [$ c]) / color ("$ color [$ c]"). $ 1. color ("reset") / ige; }}} print STDOUT $ line;}  

Se lo salvi come color in una directory che si trova nel tuo $ PATH e rendilo eseguibile ( chmod + x / usr / bin / color ), puoi colorare il modello corrispondente in questo modo:

  echo -e "foo \ nbar \ nbaz \ nbib "| color -l foo, bib 

Questo produrrà:

enter image description here

Come scritto, lo script ha colori predefiniti per 10 diversi modelli, quindi assegnargli un elenco separato da virgole come nell'esempio sopra colorerà ciascuno dei motivi abbinati in un colore diverso.

ryanmjacobs
2014-12-07 12:48:54 UTC
view on stackexchange narkive permalink

Sono un fan dell'highlighter di Paolo Antinori. https://github.com/paoloantinori/hhighlighter

Un lato positivo di questo comando è che può evidenziare fino a 10 parole con colori unici. comando a h con le parole da evidenziare.

Ad es tail -f /var/log/somelog.log | h "ERROR" produrrà:

demo-1


Alcuni esempi dal suo sito:

demo-2 demo-3

slebetman
2014-12-05 18:29:39 UTC
view on stackexchange narkive permalink

Ho scritto un programma per farlo qualche tempo fa. Lo chiamo cgrep (per color grep).

Puoi scaricarlo copiando la sezione del codice da qui in un file vuoto: http://wiki.tcl.tk/38096

Quindi rendi il file eseguibile e copialo in una delle tue normali directory bin.

È scritto in tcl quindi è necessario che tcl sia installato (8.5 e superiori). Ma la maggior parte delle distribuzioni Linux avrebbe comunque tcl installato poiché molti software lo usano (gitk, configurazione del kernel, ecc.).

La sintassi per la colorazione è semplice: opzione opzione regex .. . Puoi avere tutte le espressioni regolari che desideri. Ecco un esempio che colorerebbe gli errori in rosso e gli avvisi in giallo:

  tail -f logfile | cgrep '^. * ATTENZIONE. * $' -fg giallo '^. * ERRORE. * $' -fg rosso -bg giallo  
Zandriy
2018-08-01 21:13:32 UTC
view on stackexchange narkive permalink

Il modo più semplice è questo, penso:

  tail -f logfile.log | grep -e 'error' -e '**'  

enter image description here

Non è necessario installare nulla.

John V
2014-12-06 02:05:41 UTC
view on stackexchange narkive permalink

Bene, sto eseguendo Fedora 21 e se digito

  grep -E \ | kk rs.c  

restituirà l'intero contenuto del file "rs.c" evidenziando eventuali occorrenze di "kk".

Questo è fondamentalmente lo stesso della [risposta di arielCo] (http://softwarerecs.stackexchange.com/a/14435/185).
@Izzy: La sintassi è però più breve, quindi direi che si qualifica come una risposta valida diversa.
@NicolasRaoul è per questo che allora ho lasciato solo un commento (ma non ho contrassegnato). Fondamentalmente, speravo che il poster si espandesse un po ';)
arielCo
2014-12-05 21:43:02 UTC
view on stackexchange narkive permalink

Un semplice trucco consiste nell'identificare anche una stringa vuota o l'inizio di una riga; entrambi risultano in una corrispondenza di lunghezza zero per tutte le righe:

  grep --color -e 'REGEXP' -e '' grep --color -e 'REGEXP' -e ^  

Oppure (sintassi regexp estesa):

  grep --color -E 'REGEXP |' egrep --color 'REGEXP |'  
La prima variante non filtrerebbe anche l'output per `REGEX`? Ho appena provato, e lo fa. Quindi non corrisponde ai requisiti (solo evidenziare, non filtrare). Ma la seconda variante fa effettivamente ciò che l'OP ha richiesto (verificato;).
@Izzy: scusa, ho avuto un errore di battitura. Grazie!
Sì, ora ha senso :) Filtra per `REGEX` (evidenzia quel termine) e per" niente "(che è" ovunque "). Posso suggerirti di includere questa piccola spiegazione (anche per chiarire cosa fa), e poi cancelliamo i nostri commenti (per la pulizia)? Grazie! Nel frattempo +1 da me :)
Lo farà, ma Fedorqui ha dato essenzialmente la stessa risposta sopra (immagino di non averla vista quando ho pubblicato la mia).
Devo ammettere che non ho visto neanche questo ... (suggerimento: non c'è "sopra" o "sotto", poiché l'ordine delle risposte dipende dal filtro che hai impostato;)
Steven Penny
2014-12-07 10:59:49 UTC
view on stackexchange narkive permalink

Puoi usare questo comando

  grep --color --context = 1000  

O più breve

  grep --col -1000  

spiegahell.com - grep --color --context

asmeurer
2014-12-08 00:54:09 UTC
view on stackexchange narkive permalink

Usa less . La stringa di ricerca trovata da / è un'espressione regolare e le occorrenze verranno evidenziate.

simesy
2018-05-23 04:29:03 UTC
view on stackexchange narkive permalink

Nel mio .bashrc ho questa funzione. Lo chiamo cgrep , ma qui gli sto dando un nome leggermente più appropriato.

  highlight () {grep -E --color "^ | $ 1" ; }  

Lo trovo utile per la coda dei log, ad esempio, dove voglio evidenziare una parola chiave ma vedere tutto quello che sta succedendo.

  tail -f / var / log / SOMELOG | evidenzia KEYWORD  
Dovuto merito: ho ricevuto il "^ |" idea da @fedorqui's risposta selezionata. Grazie :)
Monty Harder
2014-12-05 23:37:02 UTC
view on stackexchange narkive permalink

Puoi semplicemente reindirizzare il tuo output a:

  sed "s / \ ([Ee] [Rr] [Rr] [Oo] [Rr] \) /` tput rev` \ 1`tput rmso` / " 

Qui sto usando un'espressione regolare che corrisponderà a" error "," ERROR "," ErRoR ", ecc. In tutte le 32 possibili varianti.

Benedikt Köppel
2014-12-07 04:48:33 UTC
view on stackexchange narkive permalink

Ho la seguente funzione definita nel mio ~/.zshrc:

  hl () {sed s / $ 1 / $ '\ e [1; 31m '\ & $' \ e [0; m '/}  

Usalo con tail -f logfile.log | hl "errore" . Aggiunge una sequenza di escape per il rosso chiaro prima della parola evidenziata e reimposta su nessun colore dopo la parola. Puoi trovare altri codici colore qui: http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...