grep: wyświetla wszystkie wyniki, ale wyróżnia pasujące wyniki wyszukiwania

43

w bashu, jeśli chcę wykonać polecenie i wyświetlić tylko linie wyjściowe, które pasują do określonego wzorca, mogę go potokować grep, jak

plik testowy pliku

hello
there
my
friends

Komenda

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

to podświetli dopasowanie wyszukiwania i wyświetli całą linię, na którą spadnie. Mogę używać -Ai -Bdo wyświetlania linii przed i po tej linii. Moje pytanie brzmi: czy możliwe jest wykonanie polecenia i wyświetlenie wszystkich danych wyjściowych w normalny sposób, ale czy podświetlić pasujące wyniki wyszukiwania, tak jak grep? więc moje wyjście byłoby

hello #highlighted
there
my
friends
ewok
źródło
3
Zobacz Przekonaj grep, aby wyświetlać wszystkie wiersze, nie tylko te z dopasowaniami (U&L) lub Kolorowane grep - przeglądanie całego pliku z podświetlonymi dopasowaniami (Przepełnienie stosu) w celu uzyskania lepszych odpowiedzi.
G-Man mówi „Przywróć Monikę”

Odpowiedzi:

38

Aby użyć GREP koloru, aby podświetlić tylko pasujące wzory, ale nie zmieniać w inny sposób wyniku:

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

Pierwszy wzór będzie pasował do wszystkich linii (wszystkie linie zostaną wydrukowane), a drugi wzór (i dowolne kolejne wzory) spowoduje, że dopasowany tekst zostanie wyróżniony kolorem.

Ponieważ pierwszy wzór pasuje do wszystkich linii, ale nie pasuje do znaku drukowalnego, nie dodaje żadnego podświetlenia kolorów, więc nie konkuruje / nie zakłóca czytelności podświetlonego tekstu.

bot779
źródło
Współpracuje z kubectl kubectl apply -k . | grep --color=always -e "^" -e "configured"w zsh
Michael Cole
Do użytku w Bash: highlight () {grep --color = always -e "^" -e $ *; }
Jon
Działa to również na FreeBSD, wystarczy zamienić pierwszy i drugi patern ( "^"musi być drugi).
Marián Černý
25

Dodaj opcję -zdo polecenia GNU grep:

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

lub krócej

grep --color=always -z 'hello' testfile
Cyrus
źródło
3
To bardzo prymitywny hack. Powoduje to traktowanie całego pliku jako pojedynczej linii. Dlatego (1), jeśli plik jest bardzo duża, może istnieć możliwość wyczerpaniu pamięci, oraz (2) jeśli plik nie zawiera wzór w ogóle , to nic nie będzie odtwarzany.
G-Man mówi „Przywróć Monikę”
W jakiej wersji grep jest obsługiwany? Na grep 2.5.4, -z nie wydaje się dostępne ...
Alex
@Alex: Użyłem GNU grep w wersji 2.6.3.
Cyrus
2
@ G-Man: więcej oszczędności zasobów:grep --color "hello\|$" file
Cyrus
@ Cyrus: Tak, to lepsza odpowiedź. Niestety jest to zasadniczo odpowiednik odpowiedzi bot779 na to pytanie i prawie identyczne z zaakceptowanymi odpowiedziami ( 1 i 2 ) na pytania, z którymi się łączyłem .
G-Man mówi „Reinstate Monica”
5

Podobnie jak w poprzedniej odpowiedzi, możesz złapać wszystkie $końce linii:

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

-E(lub --extended-regexp) oznacza, że ​​znaki specjalne muszą być poprzedzone znakiem ucieczki \. Podczas jego używania |będzie traktowany jako wyrażenie regularne „LUB”.

Grep |$będzie również łapał i drukował wszystkie linie, które mają koniec, ale ponieważ $ jest ukrytym znakiem, nie można go wyróżnić.

Aktualizacja:

Jeśli chcesz wydrukować wszystkie dane wyjściowe, ale także zwrócić kod wyjścia , niezależnie od tego, czy znaleziono dopasowanie, możesz użyć polecenia perl:

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

Jeśli wolisz sed - oto przykład, jak wyróżnić wszystkie dopasowania + zwrócić kod wyjścia, jeśli nie znaleziono dopasowania: https://askubuntu.com/a/1200851/670392

Noam Manos
źródło
2

Ten działa zarówno z GNU grep, jak i grep na FreeBSD:

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

Odpowiada tekstowi „hello” lub ( \|) nie drukowalnego ciągu zerowego na końcu każdej linii ( $). Dlatego każda linia jest drukowana, ale podświetlone jest tylko „cześć”.

Możliwe, że już --color=autoskonfigurowałeś swoją powłokę. Wtedy najprawdopodobniej nie musisz określać --color=always:

grep 'hello\|$'

Możesz także uprościć wersję, używając egrep(z rozszerzonymi wyrażeniami regularnymi), gdzie |dla wyrażenia „lub” nie trzeba wstawiać znaku ucieczki:

egrep 'hello|$'
Marián Černý
źródło
To nie odpowiada, jak wyświetlić wszystkie linie wejściowe.
Chris Page
@ChrisPage Powiedziałbym, że tak: dlatego każda linia jest drukowana, ale tylko „cześć” jest podświetlona.
Marián Černý
0

Dodanie do górnej odpowiedzi powyżej. Wspomniana w komentarzach funkcja wyróżnienia {} działa tylko wtedy, gdy przesyłane są do niej dane. Poniższy alias, choć nie idealny, jest bardziej użyteczny:

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

Działa to z poleceniami takimi jak:

greph foo bar.txt

cat bar.txt | greph foo
rpmohn
źródło