Czy można filtrować wyjście ogona?

11

Chciałbym ogonić plik, ale tylko linie wyjściowe zawierające określony ciąg znaków. czy to możliwe?

Abe Miessler
źródło

Odpowiedzi:

32

użyj grep. Jest zbudowany tylko do tego celu.

Aby znaleźć linie z ogona / var / log / syslog, które zawierają „cron”, po prostu uruchom:

tail -f /var/log/syslog | grep cron

A ponieważ akceptuje wszystko ponad standardowe wejście, możesz użyć go również na wyjściu dowolnego innego polecenia, przesyłając potoki w taki sam sposób jak powyżej (używając symbolu |).

Ryan H.
źródło
8
Chociaż jest to zasadniczo słuszne, ważne jest, aby zdawać sobie sprawę, że grepbędzie buforowane, gdy będzie używane nieinteraktywnie, na przykład gdy jest częścią dłuższego rurociągu. GNU grep 2.5.1 oferuje --line-bufferedopcję obejścia tego problemu, gdy eliminacja grep z potoku nie jest opcją. (Kiedy mówię, że grep zbuforuje, to znaczy, że nie zobaczysz danych wyjściowych, dopóki bufor nie osiągnie czegoś w rodzaju 4k.)
kojiro
Aby uzupełnić poprzedni komentarz, „tail -f” w nowoczesnym systemie Linux będzie działać w pętli, czekając na więcej danych wejściowych w pliku syslog. Aby polecenie faktycznie zakończyło się zawartością pliku, pomiń przełącznik -f: tail / var / log / syslog | grep cron
Gnudiff
7
tail -f /var/log/messages | grep "myfilterword"

Mam nadzieję, że to pomaga.

pablo
źródło
4

Oto kilka innych pomysłów, które choć nie są tak proste, mogą oferować ciekawą dodatkową elastyczność:

Po pierwsze, możesz filtrować za pomocą awk zamiast grep:

tail -f /var/log/messages | awk '/myfilterword/'

to działa dokładnie tak samo jak w przykładzie grep. Możesz rozwinąć tę kwestię, korzystając z mocy awk, na przykład:

tail -f /var/log/messages | \
awk '/myfilterword/ { for (i=6; i<=NF; i++) printf("%s ", $i); printf("\n")}'

który wypisze od 6. do ostatniego pola wyniku (pola są oddzielone białymi spacjami)

Innym podobnym pomysłem jest użycie Perla One-Liner:

tail -f /var/log/messages | perl -ne "/myfilterword/ and print"

to działa dokładnie tak jak grep. Może chcesz licznik numerów linii i tylko 6. pole? Co powiesz na to:

tail -f /var/log/messages | \ 
perl -lane "/myfilterword/ and printf \"%6d %s\n\",++\$a,\$F[6]"

Oczywiście wszystkie tego rodzaju rzeczy można wykonać również za pomocą innych narzędzi, ale chciałem zilustrować, że istnieją fajne sposoby używania bardziej ogólnych języków, takich jak awk lub perl.

Phil Hollenback
źródło
+1 świetne opracowanie, jak rozwinąć dalej niż grep!
pablo
2

Kolejna sztuczka, na którą warto zwrócić uwagę, jeśli masz plik CSV z nagłówkami, które chcesz pominąć, np .:

% cat data.txt
fruit        dessert        calories
Apple        Pie            770
Banana       Pudding        625
Cherry       Cobbler        990
% tail -n +2 data.txt
Apple        Pie            770
Banana       Pudding        625
Cherry       Cobbler        990

Nie ma znaczenia, jak długo trwa wejście tail, +n -2pominie pierwszy wiersz.

JeffG
źródło