grep: Alle Ausgaben anzeigen, aber Suchübereinstimmungen markieren

38

Wenn ich in Bash einen Befehl ausführen und nur Ausgabezeilen anzeigen möchte, die einem bestimmten Muster entsprechen, kann ich ihn grepwie folgt weiterleiten

Datei Testdatei

hello
there
my
friends

Befehl

$ cat testfile | grep 'hello'
hello #this will be highlightd

Dadurch wird die Suchübereinstimmung hervorgehoben und die gesamte Zeile angezeigt, auf die sie fällt. Ich kann Zeilen vor und nach dieser Zeile verwenden -Aund -Banzeigen. Meine Frage ist, ob es möglich ist, den Befehl auszuführen und alle Ausgaben wie gewohnt anzuzeigen, aber die Suchübereinstimmungen wie bei grep hervorzuheben? so wäre meine Ausgabe

hello #highlighted
there
my
friends
ewok
quelle

Antworten:

38

So verwenden Sie ein Farb-GREP, um nur übereinstimmende Muster hervorzuheben, die Ausgabe jedoch nicht anderweitig zu ändern:

grep --color=always -e "^" -e "hello" testfile

Das erste Muster stimmt mit allen Zeilen überein (alle Zeilen werden gedruckt). Das zweite Muster (und alle folgenden Muster) bewirken, dass der übereinstimmende Text farblich hervorgehoben wird.

Da das erste Muster mit allen Zeilen übereinstimmt, jedoch nicht mit einem druckbaren Zeichen übereinstimmt, werden keine farblichen Hervorhebungen hinzugefügt, sodass die Lesbarkeit des hervorgehobenen Textes nicht konkurriert oder beeinträchtigt wird.

bot779
quelle
Arbeitet mit kubectl kubectl apply -k . | grep --color=always -e "^" -e "configured"in zsh
Michael Cole
Zur Verwendung in Bash: Highlight () {grep --color = immer -e "^" -e $ *; }
Jon
Dies funktioniert auch unter FreeBSD. Sie müssen nur das erste und das zweite Muster austauschen ( "^"müssen das zweite sein).
Marián Černý
25

Fügen Sie -zIhrem GNU grep-Befehl eine Option hinzu :

cat testfile | grep --color=always -z 'hello'

oder kürzer

grep --color=always -z 'hello' testfile
Cyrus
quelle
3
Dies ist ein sehr grober Hack. Dadurch wird die gesamte Datei als einzelne Zeile behandelt. Daher (1) , wenn die Datei sehr groß ist, besteht eine Möglichkeit der Erinnerung an knapp sein kann, und (2) wenn die Datei nicht das Muster enthält überhaupt , dann wird nichts ausgegeben.
G-Man sagt "Reinstate Monica"
Auf welcher Version von grep wird dies unterstützt? Auf grep 2.5.4 scheint -z nicht verfügbar zu sein ...
Alex
@ Alex: Ich habe GNU grep Version 2.6.3 verwendet.
Cyrus
2
@ G-Man: mehr Ressourcen sparen:grep --color "hello\|$" file
Cyrus
@ Cyrus: Ja, das ist eine bessere Antwort. Leider entspricht es im Wesentlichen der Antwort von bot779 auf diese Frage und ist fast identisch mit den akzeptierten Antworten ( 1 und 2 ) auf die Fragen, mit denen ich verlinkt habe.
G-Man sagt "Reinstate Monica"
3

Ähnlich wie bei der vorherigen Antwort können Sie alle $Zeilenenden abfangen :

cat testfile | grep --color -E "hello|$"

-E(oder --extended-regexp) bedeutet, dass Sonderzeichen mit maskiert werden müssen \. Wenn Sie es verwenden, |wird es als regulärer "ODER" -Zustand behandelt.

Grep |$fängt und druckt auch alle Zeilen, die ein Ende haben. Da $ jedoch ein verstecktes Zeichen ist, kann es nicht hervorgehoben werden.

Aktualisieren:

Wenn Sie die gesamte Ausgabe drucken möchten, aber auch den Exit-Code zurückgeben möchten , unabhängig davon, ob eine Übereinstimmung gefunden wurde oder nicht, können Sie den Befehl perl verwenden:

cat testfile | \
perl -pe 'BEGIN {$status=1} END {exit $status} $status=0 if /hello/;'

Wenn Sie sed bevorzugen - Hier ist ein Beispiel, wie Sie alle Übereinstimmungen markieren + den Exit-Code zurückgeben, wenn keine Übereinstimmung gefunden wurde: /ubuntu//a/1200851/670392

Noam Manos
quelle
2

Dieser funktioniert sowohl mit GNU grep als auch mit grep unter FreeBSD:

grep --color=always 'hello\|$'

Es entspricht dem Text "Hallo" oder ( \|) der nicht druckbaren Nullzeichenfolge am Ende jeder Zeile ( $). Deshalb wird jede Zeile gedruckt, aber nur "Hallo" wird hervorgehoben.

Möglicherweise haben Sie bereits --color=autoin Ihrer Shell konfiguriert. Dann müssen Sie höchstwahrscheinlich nicht angeben --color=always:

grep 'hello\|$'

Sie können die Version auch vereinfachen, indem Sie egrep(mit erweiterten regulären Ausdrücken) verwenden, wobei |für den Ausdruck "oder" kein Escapezeichen erforderlich ist:

egrep 'hello|$'
Marián Černý
quelle
Dies beantwortet nicht die Anzeige aller Eingabezeilen.
Chris Seite
@ChrisPage Ich würde sagen, dass dies der Fall ist: Deshalb wird jede Zeile gedruckt, aber nur "Hallo" wird hervorgehoben.
Marián Černý
0

Hinzufügen zur obersten Antwort oben. Die in den Kommentaren erwähnte Hervorhebungsfunktion {} funktioniert nur, wenn Daten in sie geleitet werden. Der folgende Alias ​​ist zwar nicht perfekt, aber nützlicher:

alias greph="grep --color=always -e^ -e"

Dies funktioniert mit Befehlen wie:

greph foo bar.txt

cat bar.txt | greph foo
rpmohn
quelle