Colorp grep - przeglądanie całego pliku z podświetlonymi dopasowaniami


509

Uważam grep, że --color=alwaysflaga jest niezwykle przydatna. Jednak grep drukuje tylko linie z dopasowaniami (chyba że poprosisz o linie kontekstu). Biorąc pod uwagę, że każda drukowana linia ma takie samo dopasowanie, wyróżnianie nie dodaje tyle możliwości, ile mogłoby.

Naprawdę chciałbym catzobaczyć plik i zobaczyć cały plik z zaznaczonymi dopasowaniami wzorca.

Czy jest jakiś sposób, aby powiedzieć grepowi, aby drukował każdą czytaną linię, niezależnie od tego, czy istnieje dopasowanie? Wiem, że mógłbym napisać skrypt uruchamiający grep w każdej linii pliku, ale byłem ciekawy, czy jest to możliwe ze standardem grep.


1
jeśli chcesz więcej niż jednego koloru dla więcej niż jednego wzoru (tj. komunikatów o błędach, ostrzeżeniach, informacjach itp.), użyjsed . sedrozwiązanie dostaje wiele kolorów kosztem dodatkowej złożoności (zamiast około 30 znaków, które mają około 60 znaków).
— Trevor Boyd Smith

Za pomocą sed możesz nawet wyróżnić + zwrócić kod wyjścia , patrz przykład: askubuntu.com/a/1200851/670392
— Noam Manos

Odpowiedzi:


797

Oto kilka sposobów, aby to zrobić:

grep --color -E 'pattern|$' file
grep --color 'pattern\|$' file
egrep --color 'pattern|$' file

152
Ta sztuczka | $ jest fajna! Dobra robota, muszę to pamiętać. Dla tych z was, którzy nie są zaznajomieni z wyrażeniami regularnymi, „wzór | $” dopasuje linie, które mają wzorzec, którego szukasz, ORAZ linie, które mają koniec - to znaczy wszystkie. Ponieważ koniec linii nie jest tak naprawdę żadnymi znakami, pokolorowana część wyniku będzie tylko twoim wzorem. Dzięki Ryan!
— zslayton

55
Możesz też pominąć „$”: egrep --color "pattern|" file(kredyt stackoverflow.com/a/7398092/50979 )
— 13ren

15
@Zack, „|” operator jest operatorem OR, a nie AND,
— JBoy

16
@Joy, używałem „ORAZ” w konwencjonalny angielski sposób, a nie logiczną logikę. Masz rację, to rzeczywiście operator „lub” - pasuje do tego i tamtego. : P Dobre wyjaśnienie.
— zslayton,

12
Wygląda na to, że „$” jest potrzebne, jeśli pasuje więcej niż jeden wzór. egrep --color "pattern1|pattern2|$". W przeciwnym razie podświetlenie kolorów nie nastąpi.
— ZaSter

91

Oto coś w tym samym stylu. Możliwe, że i tak będziesz używać mniej, więc spróbuj tego:

less -p pattern file

Podświetli wzór i przejdzie do pierwszego wystąpienia w pliku.


4
Działa również z orurowaniem (czytanie ze stdinga) przy użyciu -:… | less -p pattern -
— phk

3
@phk: Możesz nawet pominąć myślnik.
— Wstrzymano do odwołania.

Ponadto dodanie tej -iopcji sprawi, że wielkość liter w dopasowaniu będzie niewrażliwa less -ip pattern file.
— steveb

... a jeśli rurociągów w ANSI-kolorowego wkładu, zapewniają lessz -Rprzełącznikiem:… | less -Rip introduction -
— Abdull

48

Chciałbym polecić ack - lepsze niż grep, narzędzie wyszukiwania mocy dla programistów .

$ ack --color --passthru --pager = Pliki wzorców „$ {PAGER: -less -R}”
$ ack --color --passthru pliki sygnatur | mniej -R
$ export ACK_PAGER_COLOR = "$ {PAGER: -less -R}"
$ ack - pliki sygnatur passthru

Uwielbiam to, ponieważ domyślnie korzysta z rekurencyjnego przeszukiwania katalogów (i jest o wiele mądrzejsze niż grep -r), obsługuje pełne wyrażenia regularne Perla (zamiast POSIXish regex(3)) i ma znacznie ładniejszy kontekst wyświetlania podczas przeszukiwania wielu plików.


2
Jednak od czasu do czasu nie znajduje tego, czego chcę, kiedy jestem pewien, że musi tam być. ackjest sprytny, ale czasem zbyt sprytny i wyklucza typ pliku, w którym było trafienie.
— Michael Piefel

4
@MPi ack -aprzeszuka wszystkie typy plików, wciąż wykluczając .git/ .svn/itp.
— efhemient

1
Fajnie jest jednak, że acknie przeszukuje moich zdjęć, więc -arobi to za dużo. Dodałem --type-set=freemarker=.ftldo siebie ~/.ackrc, aby podać jeden przykład.
— Michael Piefel

3
Po kilku poprawkach w konfiguracji grep już robi wszystko, co robi, jest szybszy i nigdy nie pomija wyników, jak czasami robią to białe listy ack. Być może zapisz swoje preferowane ustawienia grep w .bashrc. Kopalnia brzmi: function () {GRP GREP_OPTIONS = "- rI --color --exclude-dir = \ git --exclude = tagi." Grep "$ @"
— Jonathan Hartley

22

Możesz użyć mojego highlightskryptu z https://github.com/kepkin/dev-shell-essentials

Jest to lepsze niż grepdlatego, że możesz podświetlić każde dopasowanie własnym kolorem .

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

Zrzut ekranu z projektu Github


3
Pytanie wyraźnie dotyczy rozwiązania używającego grep, które jest standardowym narzędziem na komputerach z * nix.
— zslayton

1
Ten skrypt jest dobry, ale nie tak dobry, jak coloutwspomniano w innej odpowiedzi.
— Jonathan Hartley,

@JonathanHartley I dlaczego tak jest? Nie widzę żadnego powodu. Poza tym ten skrypt używa znacznie prostszej implementacji niż colout, co jest dobre, jeśli chcesz sprawdzić, co robi.
— HelloGoodbye,

@HelloGoodbye Tak, w porządku. Powinienem wstrzymać się od wyroku. colout jest bardziej dokładny i potężny, ale masz rację, że jest odpowiednio bardziej skomplikowany w użyciu i inżynierii wstecznej.
— Jonathan Hartley

@JonathanHartley To ma sens, że ma większą moc!
— HelloGoodbye 15.01.2019

19

Możesz także utworzyć alias. Dodaj tę funkcję do swojego .bashrc (lub .bash_profile w systemie OSX)

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

Możesz teraz używać takiego aliasu: „ ifconfig | grepe inet” lub „ grepe css index.html”.

(PS: nie zapomnij source ~/.bashrcprzeładować bashrc w bieżącej sesji)


możesz także użyć po prostu egrep, jeśli jest dostępny w twoim systemie.
— Tom

1
Przekazanie wyniku tego w celu zmniejszenia traci informacje o kolorze. Jak mógłbyś temu zapobiec?
— Connor Clark,

5
@ Korzystanie z Hoten --color=alwayszamiast--color
— limp_chimp

3
Aby lessinterpretować kody kolorów, użyj less -R.
— Eliah Kagan

Nieocenione użycie 2 $ nie jest całkowicie bezpieczne. W skrócie wolałbym wykonać funkcję grepe () {local pattern = "$ 1" shift egrep --color "$ pattern | ^" "$ @"}} Przepraszamy za bałagan z formatowaniem.
— Robert Klemme,

16

Użyj coloutprogramu: http://nojhan.github.io/colout/

Służy do dodawania wyróżnień kolorów do strumienia tekstowego. Biorąc pod uwagę wyrażenie regularne i kolor (np. „Czerwony”), odtwarza strumień tekstowy z podświetlonymi dopasowaniami. na przykład:

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

Możesz połączyć wiele wywołań, aby dodać wiele różnych wyróżnień kolorów:

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

Lub możesz osiągnąć to samo, używając wyrażenia regularnego z N grupami (części wyrażenia w nawiasach), a następnie oddzielonej przecinkami listy N kolorów.

vagrant status | \
    colout \
        '\''(^.+  running)|(^.+suspended)|(^.+not running)'\'' \
        green,yellow,red

1
Jak zauważono w innym miejscu, pytanie wyraźnie dotyczyło rozwiązania wykorzystującego grep, które jest standardowym narzędziem na komputerach z * nix.
— zslayton

4
@Zack ok, przepraszam. W rzeczywistości, jeśli rozwiążesz problem poza nim grep, a jest on już rozwinięty w odpowiedziach, coloutjest to najlepsze rozwiązanie problemu, jaki miałeś, najlepsze, o czym jestem świadomy. Zgodnie z filozofią UNIX, programy powinny być napisane, aby zrobić jedną rzecz dobrze. Bo grepfiltruje strumień tekstu. Bo coloutto jest kolorowanie lub wyróżnianie strumienia tekstu.
— user2683246

To najlepsza odpowiedź, ponieważ może stosować wiele różnych kolorowych podświetleń i coloutjest tak bardzo użytecznym narzędziem. Naucz się tego raz, używaj go w wielu sytuacjach, zamiast uczyć się jednego narzędzia do podświetlania plików dziennika, drugiego do podświetlania wyników testowych itp.
— Jonathan Hartley

9

Używam rcg z „Linux Server Hacks”, O'Reilly. Jest idealny do tego, czego chcesz i może wyróżniać wiele wyrażeń w różnych kolorach.

#!/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
}

7

-zRozwiązaniem dla grep jest również bardzo śliskie!

cat file1 | grep -z "pattern"

co robi ta łania? -z mówi grepowi, aby używał ASCII NUL jako separatora linii ...
— vy32 31.10.19

6

Dodałem to do moich .bash_aliases:

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

3

Aby podświetlić wzorce podczas przeglądania całego pliku, h może to zrobić.

Dodatkowo używa różnych kolorów dla różnych wzorów.

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

Możesz także przesyłać dane wyjściowe do hdo w less -Rcelu lepszego odczytu.

Aby grep i użyć 1 koloru dla każdego wzoru, cxpgrep może być dobrym dopasowaniem.


1

Ok, to jest jeden sposób,

wc -l filename

poda ci liczbę linii - powiedz NN, to możesz zrobić

grep -C NN --color=always filename

3
„-C 2147483647”, jeśli nie chcesz najpierw wc. Używanie dużej liczby tutaj nie wydaje się spowalniać rzeczy.
— barrycarter

1

Oto skrypt powłoki, który korzysta z funkcji gsub Awk, aby zastąpić szukany tekst odpowiednią sekwencją zmiany znaczenia, aby wyświetlać go na czerwono:

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

Używaj go w ten sposób:

$ ./cgrep pattern [file]

Niestety nie ma wszystkich funkcji grep.

Więcej informacji można znaleźć w artykule „ So You Like Colour ” w Linux Journal


1

Jedna inna odpowiedź wspomniała o przełączniku grep -Cn, który zawiera n wierszy kontekstu. Czasami robię to z n = 99 jako szybki i brudny sposób na uzyskanie [przynajmniej] pełnego kontekstu, gdy wzorzec egrep wydaje się zbyt wierny lub gdy jestem na komputerze, na którym nie zainstalowałem rcg i / lub ccze.

Niedawno odkryłem, cczektóry jest bardziej wydajnym koloryzatorem. Moją jedyną skargą jest to, że jest zorientowany na ekran (jak less, którego nigdy nie używam z tego powodu), chyba że podasz przełącznik -A dla wyjścia „surowego ANSI”.

+1 za rcgwzmiankę powyżej. Nadal jest moim ulubionym, ponieważ można go łatwo dostosować w aliasie. Coś takiego jest zwykle w moim ~ / .bashrc:

alias tailc = 'tail -f / my / app / log / file | rcg wyślij „BOLD GREEN” otrzymaj „CYAN” błąd „RED”


1

inny brudny sposób:

grep -A80 -B80 --color FIND_THIS IN_FILE

Zrobiłem

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

w bashrc.


1
jest to problematyczne, jeśli nie ma tam rzeczy, których szukasz. Powiedz z powodu błędu, w którym to przypadku nic nie otrzymasz.
— Paul Rubel,


0

Jeśli chcesz wyróżnić kilka wzorów w różnych kolorach, zobacz ten skrypt bash.

Podstawowe użycie:

echo warn error debug info 10 nil | colog

Możesz zmieniać wzory i kolory podczas uruchamiania, naciskając jeden klawisz, a następnie klawisz Enter.


0

Używam następującego polecenia w podobnym celu:

grep -C 100 searchtext file

Powie to grep, aby wydrukować 100 * 2 wierszy kontekstu przed i po podświetlonym wyszukiwanym tekście.


0

Oto moje podejście , zainspirowane rozwiązaniem @ 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[@]}")
}

To akceptuje wiele argumentów (ale nie pozwala ci dostosowywać kolorów). Przykład:

$ noisy_command | highlight ERROR WARN

-1

Czy jest jakiś sposób, aby powiedzieć grepowi, aby drukował każdą czytaną linię, niezależnie od tego, czy istnieje dopasowanie?

Opcja -C999załatwi sprawę w przypadku braku opcji wyświetlania wszystkich linii kontekstu. Większość innych wariantów grep również to obsługuje. Jednak: 1) nie jest generowany żaden wynik, gdy nie znaleziono dopasowania i 2) ta opcja ma negatywny wpływ na wydajność grep: gdy -Cwartość jest duża, to wiele linii może wymagać tymczasowego przechowywania w pamięci, aby grep mógł określić, które linie kontekstu do wyświetlenia, gdy nastąpi dopasowanie. Zauważ, że implementacje grep nie ładują plików wejściowych, a raczej odczytują kilka wierszy lub używają przesuwanego okna nad danymi wejściowymi. Kontekst „przed częścią” musi być przechowywany w oknie (pamięci), aby wyprowadzić linie kontekstu „przed” później, gdy zostanie znalezione dopasowanie.

Wzorzec taki jak ^|PATTERNlub PATTERN|$dowolny pod-wzorzec pasujący do pustych elementów, na przykład, [^ -~]?|PATTERNjest fajną sztuczką. Jednak 1) te wzory nie pokazują niepasujących linii podświetlonych jako kontekst i 2) nie można tego użyć w połączeniu z niektórymi innymi opcjami grep, takimi jak -Fi -wna przykład.

Żadne z tych podejść nie jest dla mnie satysfakcjonujące. Używam ugrep i ulepszonego grep z opcją -ywydajnego wyświetlania wszystkich niedopasowanych danych wyjściowych jako podświetlonych kolorem linii kontekstu. Inne narzędzia podobne do grep, takie jak ag i ripgrep, oferują również opcję przekazywania. Ale ugrep jest kompatybilny z GNU / BSD grep i oferuje super zestaw opcji grep, takich jak -yi -Q. Na przykład oto, co -ypokazuje opcja w połączeniu z -Q(interaktywny interfejs zapytania do wprowadzania wzorców):

ugrep -Q -y FILE ...

Po co głosować bez komentarza? Wspominanie o alternatywnych narzędziach grep, takich jak niektóre inne odpowiedzi, jest więcej niż uczciwe.
— Dr Alex RE
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.