Colorized grep - Anzeigen der gesamten Datei mit hervorgehobenen Übereinstimmungen

509

ich finde grep die --color=alwaysFlagge enorm nützlich. Grep druckt jedoch nur Zeilen mit Übereinstimmungen (es sei denn, Sie fragen nach Kontextzeilen). Da jede Zeile, die gedruckt wird, eine Übereinstimmung aufweist, bietet die Hervorhebung nicht so viele Funktionen wie möglich.

Ich würde wirklich gerne cat eine Datei und die gesamte Datei mit den hervorgehobenen Musterübereinstimmungen sehen.

Kann ich grep auf irgendeine Weise anweisen, jede gelesene Zeile zu drucken, unabhängig davon, ob eine Übereinstimmung vorliegt? Ich weiß, dass ich ein Skript schreiben kann, um grep in jeder Zeile einer Datei auszuführen, aber ich war neugierig, ob dies mit Standard möglich ist grep.

zslayton
quelle
1
Wenn Sie mehr als eine Farbe für mehr als ein Muster wünschen (z. B. Fehler-, Warn-, Info- usw. Meldungen), verwenden Siesed . Mit der sedLösung erhalten Sie mehrere Farben auf Kosten der zusätzlichen Komplexität (anstelle von etwa 30 Zeichen haben Sie etwa 60 Zeichen).
Trevor Boyd Smith
Mit sed können Sie sogar den Exit-Code markieren + zurückgeben , siehe Beispiel: askubuntu.com/a/1200851/670392
Noam Manos

Antworten:

797

Hier sind einige Möglichkeiten, dies zu tun:

grep --color -E 'pattern|$' file
grep --color 'pattern\|$' file
egrep --color 'pattern|$' file
Ryan Oberoi
quelle
152
Dieser Trick ist ordentlich! Gut gemacht, daran muss ich mich erinnern. Für diejenigen unter Ihnen, die nicht mit regulären Ausdrücken vertraut sind, stimmt "pattern | $" mit Zeilen überein, die das gesuchte Muster haben, UND mit Zeilen, die ein Ende haben - das heißt, alle. Da das Ende einer Zeile eigentlich keine Zeichen enthält, ist der kolorierte Teil der Ausgabe nur Ihr Muster. Danke Ryan!
Zslayton
55
Sie können auch das "$" weglassen: egrep --color "pattern|" file(credit stackoverflow.com/a/7398092/50979 )
13ren
15
@Zack, das "|" Operator ist ein ODER-Operator, kein UND,
JBoy
16
@JBoy, ich habe 'AND' eher auf herkömmliche englische als auf boolesche Weise verwendet. Sie haben Recht, es ist in der Tat ein 'oder' Operator - es passt zu diesem und jenem. : P Gute Klarstellung.
Zslayton
12
Es scheint, dass das "$" benötigt wird, wenn mehr als ein Muster übereinstimmt. egrep --color "pattern1|pattern2|$". Andernfalls erfolgt die Farbhervorhebung nicht.
ZaSter
91

Hier ist etwas in die gleiche Richtung. Die Chancen stehen gut, dass Sie sowieso weniger verbrauchen. Versuchen Sie Folgendes:

less -p pattern file

Das Muster wird hervorgehoben und zum ersten Vorkommen in der Datei gesprungen.

Bis auf weiteres angehalten.
quelle
4
Funktioniert auch mit Rohrleitungen (Lesen von stding) mit -:… | less -p pattern -
phk
3
@phk: Du kannst sogar den Bindestrich weglassen.
Bis auf weiteres angehalten.
Wenn Sie die -iOption hinzufügen, wird die Übereinstimmung zwischen Groß- und Kleinschreibung nicht berücksichtigt less -ip pattern file.
Steveb
... und wenn Sie einen ANSI-farbigen Eingang verwenden, stellen Sie lessden -RSchalter … | less -Rip introduction -
bereit
48

Ich möchte ack empfehlen - besser als grep, ein Power-Suchwerkzeug für Programmierer .

$ ack --color --passthru --pager = "$ {PAGER: -less -R}" Musterdateien
$ ack --color --passthru Musterdateien | weniger -R
$ export ACK_PAGER_COLOR = "$ {PAGER: -less -R}"
$ ack --passthru Musterdateien

Ich liebe es, weil es standardmäßig rekursiv in Verzeichnissen durchsucht wird (und so viel intelligenter ist als grep -r), reguläre Perl-Ausdrücke (anstelle von POSIXish regex(3)) unterstützt und beim Durchsuchen vieler Dateien eine viel schönere Kontextanzeige hat.

kurzlebig
quelle
2
Von Zeit zu Zeit findet es jedoch nicht, was ich will, wenn ich sicher bin, dass es da sein muss. ackist klug, aber manchmal zu klug, und es schloss den Dateityp aus, in dem der Treffer war.
Michael Piefel
4
@MPi ack -awird alle Dateitypen durchsuchen, während immer noch .git/ .svn/usw. ausgeschlossen sind
Ephemient
1
Es ist jedoch cool, ackmeine Bilder nicht zu durchsuchen, also -azu viel. Ich habe --type-set=freemarker=.ftlzu meiner ~/.ackrc, um ein Beispiel zu geben.
Michael Piefel
3
Mit ein paar Konfigurationsänderungen erledigt grep bereits alles, was ack tut, ist schneller und lässt niemals Ergebnisse aus, wie es die Whitelists von ack manchmal tun. Speichern Sie möglicherweise Ihre bevorzugten Grep-Einstellungen in .bashrc. Meins lautet: function grp () {GREP_OPTIONS = "- rI --color --exclude-dir = \. Git --exclude = tags" grep "$ @"
Jonathan Hartley

22

Sie können mein highlightSkript unter https://github.com/kepkin/dev-shell-essentials verwenden

Es ist besser, als grepweil Sie jedes Spiel mit seiner eigenen Farbe hervorheben können .

$ command_here | highlight green "input" | highlight red "output"

Screenshot vom Github-Projekt


3
Die Frage wurde ausdrücklich nach einer Lösung mit gestellt grep, die ein Standarddienstprogramm auf Computern ist, auf denen * nix ausgeführt wird.
Zslayton

1
Dieses Skript ist gut, aber nicht so gut wie coloutin einer anderen Antwort erwähnt.
Jonathan Hartley

@ JonathanHartley Und warum ist das so? Ich sehe keinen Grund dafür. Außerdem verwendet dieses Skript eine viel einfachere Implementierung als colout, was gut ist, wenn Sie überprüfen möchten, was es tut.
HelloGoodbye

@HelloGoodbye Ja, fair genug. Ich sollte das Urteil zurückhalten. colout ist gründlicher und leistungsfähiger, aber Sie haben Recht, dass die Verwendung und das Reverse Engineering entsprechend komplexer sind.
Jonathan Hartley

@ JonathanHartley Es macht Sinn, dass es mächtiger ist!
HelloGoodbye

19

Sie können auch einen Alias ​​erstellen. Fügen Sie diese Funktion in Ihr .bashrc (oder .bash_profile auf osx) ein.

function grepe {
    grep --color -E "$1|$" $2
}

Sie können den Alias ​​jetzt wie folgt verwenden: " ifconfig | grepe inet" oder " grepe css index.html".

(PS: Vergiss nicht, source ~/.bashrcbashrc in der aktuellen Sitzung neu zu laden)


Sie können auch nur egrep verwenden, wenn es auf Ihrem System verfügbar ist.
Tom

1
Wenn Sie das Ergebnis auf weniger leiten, verlieren Sie die Farbinformationen. Wie würden Sie das verhindern?
Connor Clark

5
@Hoten verwenden --color=alwaysanstelle von--color
limp_chimp

3
lessVerwenden Sie zum Interpretieren der Farbcodes less -R.
Eliah Kagan

Die nicht zitierte Verwendung von 2 US-Dollar ist nicht leer. In einer Bash würde ich lieber die Funktion grepe () {local pattern = "$ 1" shift egrep --color "$ pattern | ^" "$ @"} ausführen. Entschuldigen Sie das Formatierungsproblem.
Robert Klemme
16

Verwenden Sie das coloutProgramm: http://nojhan.github.io/colout/

Es wurde entwickelt, um einem Textstrom farbliche Hervorhebungen hinzuzufügen. Bei einem regulären Ausdruck und einer Farbe (z. B. "Rot") wird ein Textstrom mit hervorgehobenen Übereinstimmungen reproduziert. z.B:

# cat logfile but highlight instances of 'ERROR' in red
colout ERROR red <logfile

Sie können mehrere Aufrufe verketten, um mehrere verschiedene Farbmarkierungen hinzuzufügen:

tail -f /var/log/nginx/access.log | \
    colout ' 5\d\d ' red | \
    colout ' 4\d\d ' yellow | \
    colout ' 3\d\d ' cyan | \
    colout ' 2\d\d ' green

Oder Sie können dasselbe erreichen, indem Sie einen regulären Ausdruck mit N Gruppen (in Klammern gesetzte Teile des regulären Ausdrucks) gefolgt von einer durch Kommas getrennten Liste von N Farben verwenden.

vagrant status | \
    colout \
        '\''(^.+  running)|(^.+suspended)|(^.+not running)'\'' \
        green,yellow,red
user2683246
quelle
1
Wie an anderer Stelle erwähnt, wurde in der Frage ausdrücklich nach einer Lösung mit grep gefragt, einem Standarddienstprogramm auf Computern, auf denen * nix ausgeführt wird.
Zslayton
4
@Zack ok, sorry. Wenn Sie das Problem darüber hinaus erweitern grepund es bereits in den Antworten erweitert ist, coloutist dies die beste Lösung für das Problem, das Sie hatten, das Beste, das mir bekannt ist. Gemäß der UNIX-Philosophie sollten Programme so geschrieben werden, dass sie eines gut machen. Denn grepes filtert Textstrom. Denn coloutes färbt oder hebt Textströme hervor.
user2683246
Dies ist die beste Antwort, da mehrere farbige Hervorhebungen angewendet werden können und coloutein äußerst nützliches Werkzeug ist. Lernen Sie es einmal, verwenden Sie es in vielen Situationen, anstatt ein Tool zum Hervorheben von Protokolldateien, ein anderes zum Hervorheben der Testausgabe usw. zu lernen
Jonathan Hartley
9

Ich benutze RCG von "Linux Server Hacks", O'Reilly. Es ist perfekt für das, was Sie wollen und kann mehrere Ausdrücke mit jeweils unterschiedlichen Farben hervorheben.

#!/usr/bin/perl -w
#
#       regexp coloured glasses - from Linux Server Hacks from O'Reilly
#
#       eg .rcg "fatal" "BOLD . YELLOW . ON_WHITE"  /var/adm/messages
#
use strict;
use Term::ANSIColor qw(:constants);

my %target = ( );

while (my $arg = shift) {
        my $clr = shift;

        if (($arg =~ /^-/) | !$clr) {
                print "Usage: rcg [regex] [color] [regex] [color] ...\n";
                exit(2);
        }

        #
        # Ugly, lazy, pathetic hack here. [Unquote]
        #
        $target{$arg} = eval($clr);

}

my $rst = RESET;

while(<>) {
        foreach my $x (keys(%target)) {
                s/($x)/$target{$x}$1$rst/g;
        }
        print
}
dave1010
quelle
7

Die -zOption für grep ist auch ziemlich schick!

cat file1 | grep -z "pattern"
Abhishek Jaisingh
quelle
Was macht das? -z weist grep an, ASCII NUL als Zeilenbegrenzer zu verwenden ...
vy32
6

Ich habe dies zu meinen .bash_aliases hinzugefügt:

highlight() {
  grep --color -E "$1|\$"
}
uronce
quelle
3

Um Muster hervorzuheben, während die gesamte Datei angezeigt wird, kann h dies tun.

Außerdem werden unterschiedliche Farben für unterschiedliche Muster verwendet.

cat FILE | h 'PAT1' 'PAT2' ...

Sie können die Ausgabe von auch hzum less -Rbesseren Lesen weiterleiten.

Um für jedes Muster 1 Farbe zu verwenden, könnte cxpgrep eine gute Passform sein.

treulz
quelle
1

Ok, das ist eine Möglichkeit,

wc -l filename

gibt Ihnen die Zeilenanzahl - sagen Sie NN, dann können Sie tun

grep -C NN --color=always filename
nik
quelle
3
"-C 2147483647", wenn Sie nicht zuerst wc möchten. Die Verwendung einer großen Anzahl hier scheint die Dinge nicht zu verlangsamen.
Barrycarter
1

Hier ist ein Shell-Skript, das die gsub-Funktion von Awk verwendet, um den gesuchten Text durch die richtige Escape-Sequenz zu ersetzen und ihn in leuchtendem Rot anzuzeigen:

#! /bin/bash
awk -vstr=$1 'BEGIN{repltext=sprintf("%c[1;31;40m&%c[0m", 0x1B,0x1B);}{gsub(str,repltext); print}' $2

Verwenden Sie es so:

$ ./cgrep pattern [file]

Leider hat es nicht alle Funktionen von grep.

Weitere Informationen finden Sie in einem Artikel " So gefällt Ihnen Farbe " im Linux Journal

Wernsey
quelle
1

Eine andere Antwort erwähnte den -Cn-Schalter von grep, der n Kontextzeilen enthält. Ich mache dies manchmal mit n = 99, um schnell und schmutzig einen Kontext zu erhalten, wenn das egrep-Muster zu fummelig erscheint oder wenn ich mich auf einem Computer befinde, auf dem ich rcg nicht installiert habe und / oder ccze.

Ich habe kürzlich entdeckt, cczewelches ein stärkerer Farbstoff ist. Meine einzige Beschwerde ist, dass es bildschirmorientiert ist (wie lessich es aus diesem Grund nie benutze), es sei denn, Sie geben den -A-Schalter für die "rohe ANSI" -Ausgabe an.

+1 für die rcgoben erwähnte Erwähnung. Es ist immer noch mein Favorit, da es so einfach ist, es in einem Alias ​​anzupassen. So etwas ist normalerweise in meinem ~ / .bashrc:

alias tailc = 'tail -f / my / app / log / file | rcg send "BOLD GREEN" empfange "CYAN" Fehler "RED" '

MarkHu
quelle
1

ein anderer schmutziger Weg:

grep -A80 -B80 --color FIND_THIS IN_FILE

Ich habe eine gemacht

alias grepa='grep -A80 -B80 --color'

in bashrc.

fly_a320
quelle
1
Dies ist problematisch, wenn die gesuchten Dinge nicht vorhanden sind. Sagen Sie aufgrund eines Fehlers, in diesem Fall erhalten Sie nichts.
Paul Rubel
0

Wenn Sie mehrere Muster mit unterschiedlichen Farben hervorheben möchten, siehe dieses Bash-Skript.

Grundlegende Verwendung:

echo warn error debug info 10 nil | colog

Sie können Muster und Farben ändern, während Sie eine Taste drücken und dann die Taste eingeben.

Edoot
quelle
0

Ich benutze folgenden Befehl für ähnliche Zwecke:

grep -C 100 searchtext file

Dies bedeutet grep, um 100 * 2 Kontextzeilen vor und nach dem hervorgehobenen Suchtext zu drucken.

Al Mamun
quelle
0

Hier ist mein Ansatz , inspiriert von der Lösung von @ kepkin:

# Adds ANSI colors to matched terms, similar to grep --color but without
# filtering unmatched lines. Example:
#   noisy_command | highlight ERROR INFO
#
# Each argument is passed into sed as a matching pattern and matches are
# colored. Multiple arguments will use separate colors.
#
# Inspired by https://stackoverflow.com/a/25357856
highlight() {
  # color cycles from 0-5, (shifted 31-36), i.e. r,g,y,b,m,c
  local color=0 patterns=()
  for term in "$@"; do
    patterns+=("$(printf 's|%s|\e[%sm\\0\e[0m|g' "${term//|/\\|}" "$(( color+31 ))")")
    color=$(( (color+1) % 6 ))
  done
  sed -f <(printf '%s\n' "${patterns[@]}")
}

Dies akzeptiert mehrere Argumente (aber Sie können die Farben nicht anpassen). Beispiel:

$ noisy_command | highlight ERROR WARN
dimo414
quelle
-1

Kann ich grep auf irgendeine Weise anweisen, jede gelesene Zeile zu drucken, unabhängig davon, ob eine Übereinstimmung vorliegt?

Option -C999führt den Trick aus, wenn keine Option zum Anzeigen aller Kontextzeilen vorhanden ist. Die meisten anderen grep-Varianten unterstützen dies ebenfalls. Jedoch: 1) wird keine Ausgabe erzeugt, wenn keine Übereinstimmung gefunden wird, und 2) diese Option wirkt sich negativ auf die Effizienz von grep aus: wenn die-C Wert groß ist, müssen möglicherweise viele Zeilen vorübergehend im Speicher gespeichert werden, damit grep bestimmt, welche Kontextzeilen verwendet werden um anzuzeigen, wann eine Übereinstimmung auftritt. Beachten Sie, dass Grep-Implementierungen keine Eingabedateien laden, sondern einige Zeilen lesen oder ein Schiebefenster über der Eingabe verwenden. Der "Vorher-Teil" des Kontexts muss in einem Fenster (Speicher) aufbewahrt werden, um die "Vorher" -Kontextzeilen später auszugeben, wenn eine Übereinstimmung gefunden wird.

Ein Muster wie ^|PATTERNoder PATTERN|$oder ein beliebiges leeres Matching-Untermuster [^ -~]?|PATTERNist ein netter Trick. 1) Diese Muster zeigen jedoch keine nicht übereinstimmenden Linien, die als Kontext hervorgehoben sind, und 2) dies kann nicht in Kombination mit einigen anderen Grep-Optionen wie -Fund verwendet werden-w .

Keiner dieser Ansätze befriedigt mich also. Ich verwende ugrep und erweitertes grep mit der Option -y, alle nicht übereinstimmenden Ausgaben effizient als farblich hervorgehobene Kontextzeilen anzuzeigen. Andere grep-ähnliche Tools wie ag und ripgrep bieten ebenfalls eine Pass-Through-Option. Aber ugrep ist kompatibel mit GNU / BSD grep und bietet eine Obermenge von grep-Optionen wie -yund -Q. Die folgende Option -ywird beispielsweise in Kombination mit -Q(interaktive Abfrage-Benutzeroberfläche zur Eingabe von Mustern) angezeigt:

ugrep -Q -y FILE ...
Dr. Alex RE
quelle
Warum dies ablehnen, ohne einen Kommentar zu hinterlassen? Es ist mehr als fair, alternative grep-Tools zu erwähnen, genau wie einige der anderen Antworten.
Dr. Alex RE