15%

Zaoszczędź 15% na wszystkich usługach hostingowych

Sprawdź swoje umiejętności i zdobądź Rabat na dowolny plan hostingowy

Użyj kodu:

Skills
Rozpocznij
23.10.2024

Jak używać polecenia `grep` do wyszukiwania informacji w plikach

Polecenie grep — skrót od Global Regular Expression Print — to narzędzie Unix/Linux, które skanuje jeden lub więcej plików wiersz po wierszu i wyświetla każdy wiersz pasujący do podanego wzorca. Jest to de facto standard wyszukiwania tekstu w każdym systemie zgodnym z POSIX, obsługuje zarówno podstawowe, jak i rozszerzone wyrażenia regularne, co umożliwia dopasowywanie wszystkiego — od prostego ciągu znaków po złożone wzorce wieloznakowe.

Jeśli potrzebujesz możliwie najkrótszej odpowiedzi: uruchom grep "pattern" filename, aby przeszukać plik, dodaj -r, aby rekurencyjnie przeszukać drzewo katalogów, -i do dopasowania bez uwzględniania wielkości liter, a -n, aby wyświetlić numery wierszy obok wyników. Poniższe sekcje omawiają temat znacznie głębiej — obejmują rzeczywiste przepływy pracy, pułapki wydajnościowe oraz zaawansowane techniki wyrażeń regularnych, które większość poradników całkowicie pomija.

Co grep faktycznie robi pod maską

grep odczytuje dane wejściowe wiersz po wierszu i stosuje automat skończony wyprowadzony z podanego wyrażenia regularnego do każdego wiersza. Implementacja GNU (domyślna w systemie Linux) używa algorytmu Boyer-Moore-Horspool dla ciągów literalnych oraz konstrukcji Thompson NFA dla wzorców wyrażeń regularnych. Ta architektura sprawia, że grep jest niezwykle szybki na dużych plikach — unika nawrotów, w przeciwieństwie do narzędzi opartych na PCRE, takich jak perl czy python.

W rodzinie GNU coreutils istnieją trzy odrębne pliki binarne:

PolecenieSilnikZastosowanie
grepBRE / ERE (z -E)Ogólne dopasowywanie wierszy
egrepERE (rozszerzone wyrażenia regularne)Skrót dla grep -E
fgrepTylko ciągi stałeNajszybszy; bez interpretacji wyrażeń regularnych
zgrepBRE / ERE na skompresowanych plikachArchiwa .gz, .bz2
pgrepDopasowywanie nazw procesówPrzeszukuje tablicę procesów, nie pliki

egrep i fgrep to przestarzałe aliasy w nowoczesnych systemach; w skryptach należy używać odpowiednio grep -E i grep -F dla zachowania przenośności.

Podstawowa składnia

grep [options] pattern [file ...]
  • pattern — ciąg znaków lub wyrażenie regularne ujęte w cudzysłów
  • file — jedna lub więcej ścieżek do plików; pominięcie powoduje odczyt ze standardowego wejścia
  • options — flagi modyfikujące zachowanie dopasowywania, format wyjścia lub wydajność

Minimalny przykład wyszukujący każdy wiersz zawierający słowo „error” w syslog:

grep "error" /var/log/syslog

Zawsze ujmuj wzorzec w cudzysłów. Wzorce bez cudzysłowów zawierające metaznaki powłoki (*, ?, [, $) zostaną rozwinięte przez powłokę, zanim grep je zobaczy, co prowadzi do cichych, nieprawidłowych wyników.

Podstawowe opcje, które każdy administrator musi znać

Przeszukiwanie wielu plików i katalogów

Podaj pliki jawnie lub użyj globowania powłoki:

grep "error" access.log error.log debug.log
grep "error" *.log

Aby przeszukać całe drzewo katalogów, użyj -r (podążaj za dowiązaniami symbolicznymi za pomocą -R):

grep -r "error" /var/log/

Pułapka: Na serwerach produkcyjnych z głęboko zagnieżdżonymi hierarchiami logów, nieograniczone -r może generować znaczące obciążenie I/O. Ogranicz zakres za pomocą --include, aby uniknąć skanowania plików binarnych lub nieistotnych rozszerzeń:

grep -r --include="*.log" "error" /var/log/

Wyszukiwanie bez uwzględniania wielkości liter (-i)

grep -i "error" application.log

Dopasowuje to error, Error, ERROR, eRrOr i każdą inną kombinację wielkości liter. Wewnętrznie GNU grep z flagą -i konwertuje zarówno wzorzec, jak i dane wejściowe na małe litery przed porównaniem, co powoduje niewielkie obciążenie przy bardzo dużych plikach.

Wyświetlanie numerów wierszy (-n)

grep -n "error" application.log

Przykładowe wyjście:

25:error occurred during processing
103:error: connection refused

Numery wierszy są niezbędne, gdy chcesz przejść bezpośrednio do dopasowania w edytorze: vim +25 application.log otwiera plik w wierszu 25.

Liczenie dopasowań (-c)

grep -c "error" application.log

Zwraca tylko liczbę pasujących wierszy, a nie same wiersze. Podczas przeszukiwania wielu plików każdy plik otrzymuje własną liczbę:

grep -c "error" *.log
access.log:0
debug.log:14
error.log:3

Odwrócone dopasowanie (-v)

grep -v "error" application.log

Zwraca każdy wiersz, który nie pasuje do wzorca. Praktyczne zastosowanie: usunięcie wierszy komentarzy z pliku konfiguracyjnego przed przekazaniem go dalej potokiem:

grep -v "^#" /etc/nginx/nginx.conf | grep -v "^$"

Usuwa to zarówno wiersze komentarzy (zaczynające się od #), jak i puste wiersze, pozostawiając tylko aktywne dyrektywy.

Dopasowywanie całych słów (-w)

grep -w "error" application.log

Bez -w wyszukiwanie error dopasowałoby również errors, error_code i myerror. Flaga -w kotwi dopasowanie do granic słów, definiowanych jako przejścia między znakami słownymi ([a-zA-Z0-9_]) a znakami niesłownymi.

Ograniczanie liczby wierszy wyjściowych (-m)

grep -m 5 "error" application.log

grep zatrzymuje odczytywanie pliku po znalezieniu 5 pasujących wierszy. W przypadku pliku logu o rozmiarze 10 GB, gdy wystarczy potwierdzić istnienie wzorca, -m 1 może skrócić czas wykonania z sekund do milisekund, ponieważ grep kończy działanie natychmiast po pierwszym dopasowaniu.

Wiersze kontekstu (-A, -B, -C)

Jedna z najrzadziej używanych funkcji. Podczas diagnozowania błędu otaczające wiersze często zawierają przyczynę źródłową:

grep -A 3 "error" application.log   # 3 lines After the match
grep -B 3 "error" application.log   # 3 lines Before the match
grep -C 3 "error" application.log   # 3 lines of Context (before and after)

To różnica między zobaczeniem error: connection refused a zobaczeniem pełnego śladu stosu lub poprzedzającego żądania, które go wywołało.

Podświetlanie kolorami (--color)

grep --color=auto "error" application.log

Większość dystrybucji ustawia alias grep='grep --color=auto' w /etc/profile.d/ lub ~/.bashrc. Użyj --color=always podczas przekazywania potokiem do less -R, aby zachować kody ANSI:

grep --color=always "error" application.log | less -R

Wyświetlanie tylko pasującej części (-o)

Domyślnie grep wyświetla cały pasujący wiersz. Flaga -o wyświetla tylko tę część wiersza, która pasuje do wzorca:

grep -o "192.[0-9]*.[0-9]*.[0-9]*" access.log

Wyodrębnia to każdy adres IPv4 z logu dostępu — jeden adres na wiersz wyjściowy — co jest idealne do przekazania potokiem do sort | uniq -c | sort -rn w celu znalezienia najbardziej aktywnych klientów.

Pomijanie nazwy pliku w wyjściu (-h) i wymuszanie jej (-H)

Podczas przeszukiwania wielu plików grep poprzedza każde dopasowanie nazwą pliku. -h pomija tę informację; -H wymusza jej wyświetlanie nawet przy przeszukiwaniu jednego pliku. Używaj -H w skryptach, aby zagwarantować spójny format wyjścia niezależnie od liczby przekazanych plików.

Wyświetlanie tylko nazw plików (-l i -L)

grep -l "error" *.log    # files that contain the pattern
grep -L "error" *.log    # files that do NOT contain the pattern

Przydatne w skryptach wdrożeniowych do identyfikowania plików konfiguracyjnych odwołujących się do przestarzałego parametru.

Wyrażenia regularne w grep

Podstawowe wyrażenia regularne (BRE)

grep domyślnie używa BRE. Kluczowe metaznaki:

MetaznakZnaczeniePrzykład
^Początek wierszagrep "^error" — wiersze zaczynające się od „error”
$Koniec wierszagrep "error$" — wiersze kończące się na „error”
.Dowolny pojedynczy znakgrep "err.r" — dopasowuje „error”, „errar” itp.
*Zero lub więcej poprzedniegogrep "err*" — „er”, „err”, „errr” itp.
[abc]Klasa znakówgrep "[aeiou]" — dowolna samogłoska
[^abc]Zanegowana klasagrep "[^0-9]" — dowolny znak niebędący cyfrą
Ucieczka metaznakugrep "." — dosłowna kropka

W BRE znaki +, ?, {, }, (, ) i | muszą być poprzedzone ukośnikiem odwrotnym, aby były traktowane jako metaznaki. Jest to częste źródło pomyłek podczas przełączania się między BRE a ERE.

Rozszerzone wyrażenia regularne (ERE) z -E

grep -E "error|failure|critical" application.log

ERE upraszcza składnię — +, ?, |, () i {} działają bez ukośników odwrotnych:

grep -E "err(or|ata)?" application.log       # matches "err", "error", "errata"
grep -E "[0-9]{1,3}.[0-9]{1,3}" access.log  # partial IP pattern
grep -E "^(ERROR|WARN|FATAL)" app.log        # lines starting with severity levels

Wyrażenia regularne zgodne z Perl (PCRE) z -P

GNU grep obsługuje PCRE za pomocą flagi -P, odblokowując wyprzedzenia, wsteczne odwołania i kwantyfikatory niezachłanne:

grep -P "(?<=user=)w+" auth.log    # extract username after "user="
grep -P "d{4}-d{2}-d{2}" app.log # ISO date format

Ważne: -P jest rozszerzeniem GNU i nie jest dostępne w BSD grep (domyślnym na macOS). Skrypty używające -P nie są przenośne bez zainstalowania GNU grep (brew install grep na macOS).

Przeszukiwanie skompresowanych plików za pomocą zgrep

Rotacja logów zazwyczaj kompresuje starsze logi za pomocą gzip. zgrep pozwala przeszukiwać je bez ręcznej dekompresji:

zgrep "error" /var/log/syslog.2.gz

Dla plików .bz2 użyj bzgrep. Dla plików .xz użyj xzgrep. Jeśli chcesz przeszukać zarówno skompresowane, jak i nieskompresowane logi jednym poleceniem:

zgrep -r "error" /var/log/

Przypadek brzegowy: zgrep wewnętrznie wywołuje zcat do dekompresji, a następnie przekazuje wynik potokiem do grep. Nie obsługuje wszystkich flag grep. Jeśli potrzebujesz -P lub -o na skompresowanych plikach, najpierw zdekompresuj do pliku tymczasowego lub użyj zcat file.gz | grep -P "pattern".

Łączenie grep z innymi poleceniami

Prawdziwa moc grep ujawnia się, gdy jest łączony z innymi narzędziami za pomocą potoków.

Filtrowanie wyjścia procesów

ps aux | grep "[n]ginx"

Sztuczka z nawiasem [n]ginx zapobiega pojawianiu się samego procesu grep w wynikach, ponieważ wzorzec [n]ginx nie pasuje do dosłownego ciągu [n]ginx na liście procesów.

Wyodrębnianie i agregowanie danych z logów

grep "error" application.log | sort | uniq -c | sort -rn | head -20

Ten potok: znajduje wszystkie wiersze z błędami, sortuje je, zlicza unikalne wystąpienia, ponownie sortuje malejąco według częstotliwości i wyświetla 20 najczęstszych błędów. Jest to technika wstępnej triażu przy każdym incydencie produkcyjnym.

Znajdowanie plików zawierających wzorzec, a następnie działanie na nich

grep -rl "deprecated_function" /var/www/html/ | xargs sed -i 's/deprecated_function/new_function/g'

grep -rl wyświetla pliki zawierające wzorzec; xargs przekazuje je do sed w celu zastąpienia w miejscu. Zawsze najpierw testuj bez -i lub użyj -i.bak, aby tworzyć kopie zapasowe.

Wyszukiwanie przez SSH

ssh user@server "grep -r 'error' /var/log/app/" | less

Możesz uruchomić grep na zdalnym serwerze i przesyłać wyniki strumieniowo do lokalnego terminala — przydatne, gdy pliki logów są zbyt duże do transferu.

Łączenie z awk do strukturalnego parsowania

grep "POST /api" access.log | awk '{print $1, $7, $9}'

grep filtruje odpowiednie wiersze; awk wyodrębnia konkretne pola (IP, URL, kod statusu). Ta kombinacja obsługuje większość zadań analizy logów bez potrzeby dedykowanej platformy agregacji logów.

Kwestie wydajnościowe

W przypadku dużych plików lub automatyzacji o wysokiej częstotliwości te optymalizacje mają znaczenie:

  • Używaj -F dla ciągów literalnych. grep -F "exact string" całkowicie pomija kompilację wyrażeń regularnych i jest mierzalnie szybszy.
  • Używaj LC_ALL=C. Ustawienie LC_ALL=C grep "pattern" file wymusza przetwarzanie w trybie jednobajtowym, co może być 2–5 razy szybsze na plikach UTF-8, ponieważ pomija obsługę znaków wielobajtowych.
  • Unikaj -r na sieciowych systemach plików. Rekurencyjny grep przez NFS lub CIFS może nasycić sieciowe I/O. Zamiast tego używaj find z -exec i jawnym określeniem zakresu ścieżek.
  • Używaj --mmap na Linux. grep --mmap używa wejścia/wyjścia mapowanego w pamięci zamiast wywołań systemowych read(), co zmniejsza narzut przy dużych plikach (niedostępne na wszystkich platformach).
  • Zrównoleglaj za pomocą xargs -P. Przy przeszukiwaniu wielu niezależnych plików podziel obciążenie:
find /var/log -name "*.log" | xargs -P 4 grep -l "error"

Uruchamia to 4 procesy grep równolegle, wykorzystując wiele rdzeni CPU.

grep a alternatywne narzędzia wyszukiwania

NarzędzieSzybkość na dużych repozytoriachObsługa wyrażeń regularnychRespektuje `.gitignore`Najlepsze zastosowanie
grepUmiarkowanaBRE/ERE/PCRENiePliki systemowe, logi, skrypty
ripgrep (rg)Bardzo szybkaPCRE2TakWyszukiwanie kodu w repozytoriach
ag (Silver Searcher)SzybkaPCRETakWyszukiwanie kodu, starsza alternatywa dla rg
ackUmiarkowanaPCRECzęściowoBazy kodu zorientowane na Perl
fgrep / grep -FNajszybszaBrak (tylko ciągi stałe)NieSkanowanie logów pod kątem stałych ciągów

Do zadań administracji systemem — skanowania /var/log, /etc lub wyjścia aktywnych procesów — grep pozostaje właściwym narzędziem, ponieważ jest powszechnie dostępny bez instalacji. Do przeszukiwania baz kodu aplikacji ripgrep jest znacznie szybszy i wygodniejszy.

Praktyczne rzeczywiste przepływy pracy

Audyt nieudanych logowań SSH

grep -i "failed password" /var/log/auth.log | grep -oP "from K[d.]+" | sort | uniq -c | sort -rn | head -10

Wyodrębnia to źródłowy IP każdej nieudanej próby logowania SSH i klasyfikuje je według częstotliwości — jest to pierwszy krok w identyfikowaniu źródeł ataków brute-force przed aktualizacją reguł zapory sieciowej.

Znajdowanie błędów konfiguracji przed ponownym uruchomieniem usługi

grep -rn "listens*443" /etc/nginx/

Potwierdza, które pliki konfiguracyjne Nginx definiują nasłuchiwanie HTTPS. Połącz z konfiguracją Certyfikatów SSL, aby sprawdzić, czy ścieżki certyfikatów wskazane w tych plikach faktycznie istnieją.

Monitorowanie pliku logu w czasie rzeczywistym

tail -f /var/log/app/production.log | grep --line-buffered "ERROR"

--line-buffered wymusza na grep opróżnianie bufora wyjściowego po każdym wierszu zamiast buforowania, co jest niezbędne przy przekazywaniu potokiem z tail -f. Bez tego możesz nie widzieć żadnego wyjścia przez minuty, mimo że dopasowania są znajdowane.

Weryfikacja wdrożonej konfiguracji

grep -c "server_name" /etc/nginx/sites-enabled/* | grep -v ":0"

Wyświetla każdą włączoną witrynę Nginx zawierającą co najmniej jedną dyrektywę server_name — szybka kontrola poprawności po wdrożeniu nowego wirtualnego hosta w środowisku VPS Hosting.

Wyodrębnianie adresów e-mail z pliku

grep -Eo "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}" contacts.txt

Flaga -o w połączeniu ze wzorcem ERE wyodrębnia tylko dopasowane adresy e-mail, jeden na wiersz, gotowe do dalszego przetwarzania.

Przeszukiwanie logów aplikacji na wielu serwerach

Na Serwerze Dedykowanym obsługującym wiele instancji aplikacji może być konieczne korelowanie logów z różnych katalogów:

grep -rh --include="*.log" "transaction_id=abc123" /var/log/app1/ /var/log/app2/ /var/log/app3/

-h pomija nazwy plików, dzięki czemu wyjście można przekazać potokiem do widoku posortowanego według znacznika czasu.

Typowe błędy i jak ich unikać

Zapominanie o cudzysłowach wokół wzorców ze spacjami:

# Wrong — shell splits "connection refused" into two arguments
grep connection refused /var/log/syslog

# Correct
grep "connection refused" /var/log/syslog

Używanie składni BRE zamiast ERE:

# Wrong in BRE — + is literal
grep "error+" app.log

# Correct — use -E or escape in BRE
grep -E "error+" app.log
grep "error+" app.log

Rekurencyjne wyszukiwanie trafiające na pliki binarne:

# Produces "Binary file matches" noise
grep -r "config" /usr/

# Correct — skip binary files
grep -r --binary-files=without-match "config" /usr/
# or equivalently
grep -rI "config" /usr/

Mylące kotwiczenie — ^ wewnątrz klasy znaków:

[^abc] oznacza „nie a, b ani c”. Znak ^ oznacza „początek wiersza” tylko wtedy, gdy pojawia się na samym początku wzorca, poza nawiasami.

Kluczowe wnioski i macierz decyzyjna

Użyj tej listy kontrolnej podczas konstruowania polecenia grep:

  • Ciąg literalny, bez potrzeby wyrażeń regularnych? Dodaj -F dla maksymalnej szybkości.
  • Nieznana wielkość liter w docelowym pliku? Dodaj -i.
  • Potrzebujesz wiedzieć, gdzie w pliku jest dopasowanie? Dodaj -n.
  • Przeszukujesz drzewo katalogów? Dodaj -r --include="*.ext", aby ograniczyć zakres wyszukiwania.
  • Duży plik, wystarczy potwierdzić istnienie? Dodaj -m 1, a grep zakończy działanie po pierwszym dopasowaniu.
  • Potrzebujesz otaczającego kontekstu do diagnozy? Dodaj -C 3.
  • Wzorzec zawiera metaznaki powłoki? Ujmij wzorzec w pojedyncze cudzysłowy: grep '$variable'.
  • Przeszukujesz skompresowane logi? Użyj zgrep lub zcat file.gz | grep.
  • Potrzebujesz alternacji lub kwantyfikatorów +/?? Dodaj -E dla ERE.
  • Potrzebujesz wyprzedzeń lub dopasowywania niezachłannego? Dodaj -P dla PCRE (tylko GNU grep).
  • Wyodrębniasz konkretny dopasowany tekst, a nie całe wiersze? Dodaj -o.
  • Przeszukujesz bazę kodu, a nie pliki systemowe? Rozważ użycie ripgrep.

Zarządzając infrastrukturą serwerową — czy to na VPS z cPanel, czy w czystym środowisku Linux — grep jest pierwszym narzędziem, po które sięgasz, gdy coś przestaje działać. Opanowanie kombinacji jego flag i możliwości łączenia z awk, sed, sort i xargs pozwala w ciągu sekund przekształcić surowe dane z logów w użyteczne informacje diagnostyczne.

W środowiskach, gdzie Hosting Poczty E-mail lub aplikacje webowe generują duże ilości ustrukturyzowanych logów, naturalnym kolejnym krokiem jest połączenie grep z potokiem agregacji logów (stos ELK, Loki lub podobne) — jednak grep pozostaje rozwiązaniem awaryjnym działającym wszędzie, zawsze, bez żadnych zależności.

Często zadawane pytania

Jaka jest różnica między grep, egrep i fgrep?

grep domyślnie używa podstawowych wyrażeń regularnych. egrep jest równoważne grep -E i używa rozszerzonych wyrażeń regularnych, gdzie +, ?, | i () działają bez ukośników odwrotnych. fgrep jest równoważne grep -F i traktuje wzorzec jako dosłowny ciąg stały bez interpretacji wyrażeń regularnych, co czyni go najszybszą opcją. Zarówno egrep, jak i fgrep to przestarzałe aliasy; w skryptach używaj odpowiednio grep -E i grep -F.

Dlaczego grep -r czasami zwraca komunikat „Binary file matches”?

grep wykrywa pliki binarne, skanując w poszukiwaniu bajtów zerowych. Gdy znajdzie dopasowanie w pliku uznanym za binarny, wyświetla ten komunikat zamiast pasującego wiersza. Pomiń pliki binarne za pomocą grep -rI (wielka litera I) lub wymuś tryb tekstowy za pomocą grep -ra (traktuj wszystkie pliki jako tekst). Używaj -I w środowisku produkcyjnym, aby uniknąć zniekształconego wyjścia spowodowanego przypadkowym dopasowaniem skompilowanych obiektów lub skompresowanych plików.

Jak wyszukiwać wzorzec zawierający ukośnik?

Ukośniki nie mają specjalnego znaczenia we wzorcach grep (w przeciwieństwie do sed czy awk). Możesz ich używać dosłownie: grep "var/log" /etc/logrotate.conf. Nie jest wymagane żadne ucieczka.

Jaki jest najszybszy sposób sprawdzenia, czy ciąg istnieje gdziekolwiek w dużym pliku?

Użyj grep -qF "string" file && echo "found". Flaga -q pomija wszystkie wyjście i kończy działanie ze statusem 0 przy pierwszym dopasowaniu lub 1 w przypadku braku dopasowania. Flaga -F wyłącza przetwarzanie wyrażeń regularnych. Łącznie grep odczytuje tylko tyle pliku, ile potrzeba, i natychmiast kończy działanie — co jest kluczowe dla plików o rozmiarze gigabajtów.

Czy grep może przeszukiwać pliki na zdalnym serwerze bez kopiowania ich lokalnie?

Tak. Przekaż przez SSH: ssh user@host "grep -r 'pattern' /var/log/". Wyszukiwanie wykonuje się na zdalnym hoście i tylko pasujące wiersze są przesyłane przez sieć. W przypadku powtarzających się wyszukiwań rozważ zamontowanie zdalnego systemu plików za pomocą sshfs i uruchamianie grep lokalnie, lub użyj scentralizowanego rozwiązania do zbierania logów, jeśli wolumen to uzasadnia.

15%

Zaoszczędź 15% na wszystkich usługach hostingowych

Sprawdź swoje umiejętności i zdobądź Rabat na dowolny plan hostingowy

Użyj kodu:

Skills
Rozpocznij