
Ich leite die Ausgabe eines grep
Befehls in einen anderen weiter grep
. Der erste grep
verwendet --color=always
, sodass die erste Übereinstimmung farbig dargestellt wird. In der Praxis bedeutet das, dass die Übereinstimmung zwischen zwei Farbcodes eingeschlossen ist, also \033[1;31m
und \033[0m
.
Das Problem besteht nun darin, dass das zweite Muster m
, wenn es ist, mit dem Farbcode der vorherigen Übereinstimmung übereinstimmt:
echo A B C | grep --color=always A | grep m
Ebenso 31
würde auch die Nummer übereinstimmen.
Gibt es einen Weg, das zu umgehen?
AKTUALISIEREN:
Ich ging davon aus, dass es selbstverständlich ist, dass das Streichholz farbig sein muss, daher ist das Entfernen --color=always
für mich keine zufriedenstellende Lösung.
Antwort1
Verwenden Sie nicht grep --color=always
, aus genau diesem Grund verfügen GNU grep
(und möglicherweise auch andere) auch über , was allein (von ) grep --color=auto
gleichwertig ist :grep --color
man grep
--color[=WHEN], --colour[=WHEN]
Surround the matched (non-empty) strings, matching lines,
context lines, file names, line numbers, byte offsets, and
separators (for fields and groups of context lines) with escape
sequences to display them in color on the terminal. The colors
are defined by the environment variable GREP_COLORS. The
deprecated environment variable GREP_COLOR is still supported,
but its setting does not have priority. WHEN is never, always,
or auto.
Ich kann nicht finden, wo dies ausführlicher dokumentiert ist, aber im Wesentlichen erkennt es, ob die Ausgabe grep
eine Datei oder ein Terminal oder eine Pipe oder was auch immer ist, und reagiert entsprechend:
$ echo foo | grep --color=always o | grep m
f[01;31mo[m[01;31mo[m
$ echo foo | grep --color=always o >outfile; grep m outfile
f[01;31mo[m[01;31mo[m
Vergleichen Sie das Obige mit
$ echo foo | grep --color o >outfile; grep m outfile
$ echo foo | grep --color o | grep m
$
Wenn Sie diese auto
Option verwenden, werden die Farben grundsätzlich nur dann gedruckt, wenn Sie sie sehen können. Das ist wirklich sehr clever und funktioniert wunderbar. So gut, dass ich Folgendes habe:
$ type grep
grep is aliased to `grep --color'
Antwort2
Dies ist übrigens genau der Grund, warum --color
standardmäßig --color=auto
und nicht verwendet wird --color=always
.
Wenn Ihr Ziel lautet: „Zeigen Sie mir alle Zeilen, die sowohl als auch enthalten, A
und m
markieren Sie die entsprechenden Zeichen A
und m
“, scheint es die einfachste Lösung zu sein, die Hervorhebungen nach allen Übereinstimmungen vorzunehmen und ein Egrep zu verwenden, um die Hervorhebungen wieder hinzuzufügen. Etwa so:
{
echo "A b";
echo "A m";
echo "B m";
echo "Another m";
} | grep 'A' | grep 'm' | egrep --color 'A|m';
Antwort3
Was ist der eigentliche Anwendungsfall? Wenn Sie A
in allen Zeilen, die auch enthalten, Farbcodes verwenden möchten m
, können Sie das grep
s einfach umkehren:
echo A B C | grep m | grep --color=always A
Alternativ, wenn Sie nach einem Literal in der Originalausgabe suchen, m
müssen Sie vorher alle Farbcodes ausschließen, grep m
aber das Ergebnis druckenmitdie Farbcodes. Eine Möglichkeit hierfür besteht darin, nl
die Zeilen der Ausgabe mit zu nummerieren, grep
für eine Zeilennummer gefolgt von m
, nur die Zeilennummern aus dieser Ausgabe zu speichern und dann mit sed -n
nur die Zeilen in der farbcodierten Ausgabe zu drucken.