Überzeugen Sie grep, alle Zeilen auszugeben, nicht nur die mit Übereinstimmungen

Überzeugen Sie grep, alle Zeilen auszugeben, nicht nur die mit Übereinstimmungen

Angenommen, ich habe die folgende Datei:

$ cat test

test line 1
test line 2
line without the search word
another line without it
test line 3 with two test words
test line 4

Gibt standardmäßig grepjede Zeile zurück, die den Suchbegriff enthält:

$ grep test test

test line 1
test line 2
test line 3 with two test words
test line 4

Wenn Sie den --colorParameter an übergeben grep, wird der Teil der Zeile hervorgehoben, der dem Suchausdruck entspricht, es werden jedoch weiterhin nur Zeilen zurückgegeben, die den Ausdruck enthalten. Gibt es eine Möglichkeit, grepjede Zeile in der Quelldatei auszugeben, aber die Übereinstimmungen hervorzuheben?

Mein aktueller, schrecklicher Hack, um dies zu erreichen (zumindest bei Dateien, die nicht über 10.000 aufeinanderfolgende Zeilen ohne Übereinstimmungen haben), ist:

$ grep -B 9999 -A 9999 test test

Screenshot der beiden Befehle

Wenn grepdies nicht möglich ist, gibt es ein anderes Befehlszeilentool, das die gleiche Funktionalität bietet? Ich habe herumgespielt mitack, aber es scheint auch keine Option dafür zu geben.

Antwort1

grep --color -E "test|$" yourfile

Was wir hier tun, ist, es mit dem $Muster und dem Testmuster abzugleichen. Offensichtlich $gibt es nichts zum Einfärben, also wird nur das Testmuster eingefärbt. Dadurch -Ewird lediglich die erweiterte Regex-Übereinstimmung aktiviert.

Sie können daraus ganz einfach eine Funktion erstellen, und zwar wie folgt:

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

Antwort2

ack --passthru --color string file

Verwenden Sie für Ubuntu und Debian ack-grep anstelle von ack

ack-grep --passthru --color string file

Antwort3

Eine andere Möglichkeit, dies zu tunrichtigUndtragbarmit grep(außer der Verwendung von zwei Regexen mit Wechsel wie in der akzeptierten Antwort) erfolgt über das Nullmuster (bzw. die Nullzeichenfolge). Es sollte mit beiden Schaltern
gleich gut funktionieren , da-E-Fgemäß der Norm:

-E
    Match using extended regular expressions. 
    [...] A null ERE shall match every line.

Und

-F
    Match using fixed strings.
    [...] A null string shall match every line.

Es geht also nur darum, zu rennen

grep -E -e '' -e 'pattern' infile

bzw.

grep -F -e '' -e 'string' infile

Antwort4

ripgrep

Verwenden Sie es ripgrepmit den folgenden --passthruParametern:

rg --passthru pattern file.txt

Es ist eines derschnellste Grepping-Tools, da es aufRusts Regex-Enginedas endliche Automaten, SIMD und aggressive Literaloptimierungen verwendet, um die Suche sehr schnell zu machen.

--passthru- Drucken Sie sowohl übereinstimmende als auch nicht übereinstimmende Zeilen.

Eine andere Möglichkeit, einen ähnlichen Effekt zu erzielen, besteht darin, Ihr Muster so zu ändern, dass es mit der leeren Zeichenfolge übereinstimmt. Wenn Sie beispielsweise mit suchen, gibt rg foo„using“ rg "^|foo"stattdessen jede Zeile in jeder durchsuchten Datei aus, aber nur Vorkommen von „foo“ werden hervorgehoben. Dieses Flag ermöglicht dasselbe Verhalten, ohne dass das Muster geändert werden muss.

verwandte Informationen