Czy mogę grepować tylko pierwsze n wierszy pliku?

126

Mam bardzo długie pliki dziennika, czy można poprosić grepa o przeszukanie tylko pierwszych 10 wierszy?

David LeBauer
źródło

Odpowiedzi:

175

Magia rur;

head -10 log.txt | grep <whatever>
Joachim Isaksson
źródło
13
możesz również przesłać dowolny strumień do head:someCmd | head -10
Stuarta Nelsona
1
Head domyślnie drukuje pierwsze 10 linii na standardowe wyjście, więc jest to ważne dla 10 liniihead log.txt | grep <whatever>
Zlemini
5
Czy istnieje sposób, aby to zrobić, korzystając z -lopcji grepa ? Chciałbym wymienić wszystkie pliki, które mają pierwsze 5 znaków RIFFD.
James M. Lay
49

Ludzie, którzy znaleźli to w Google, musieli przeszukać pierwsze nwiersze wielu plików, ale wydrukować tylko pasujące nazwy plików. użyłem

 gawk 'FNR>10 {nextfile} /pattern/ { print FILENAME ; nextfile }' filenames

W FNR..nextfileprzestaje przetwarzać plik raz 10 linii zostały zaobserwowane. Wyświetla //..{}nazwę pliku i przechodzi dalej, gdy pojawi się pierwsze dopasowanie w danym pliku. Aby cytować nazwy plików dla innych programów, użyj

 gawk 'FNR>10 {nextfile} /pattern/ { print "\"" FILENAME "\"" ; nextfile }' filenames
cxw
źródło
9
Byłem jednym z tych ludzi, którzy znaleźli to w Google. Dzięki!
Floris
dla mnie ten kod wypisał pełną ścieżkę do pliku. Właśnie tego potrzebowałem. Również FNR=1przeszuka tylko pierwszą linię. Dzięki!
Brian W
2
Aby to zrobić rekurencyjnie w katalogu:find ./path -type -f -exec awk 'FNR>10 {nextfile} /pattern/ { print FILENAME ; nextfile }' '{}' +
OrangeDog
1
Dzięki @OrangeDog. Jedna niewielka korekta: powinna być-type f
David Siegal
26

Lub użyj awkdo pojedynczego procesu bez |:

awk '/your_regexp/ && NR < 11' INPUTFILE

W każdym wierszu, jeśli your_regexppasuje, a liczba rekordów (wierszy) jest mniejsza niż 11, wykonuje domyślną akcję (czyli drukowanie wiersza wejściowego).

Lub użyj sed:

sed -n '/your_regexp/p;10q' INPUTFILE 

Sprawdza twoje wyrażenie regularne i wypisuje wiersz ( -noznacza to, że nie drukuj danych wejściowych, co w przeciwnym razie jest wartością domyślną) i kończy pracę zaraz po 10. linii.

Zsolt Botykai
źródło
1
Dlaczego nie zrezygnować 10-tego? (patrz rozwiązanie sed)
potong
awk '{ if ( NR <= 10 ) { if(index($0,"ab") > 0) { print $0; } } else { exit; } }' textfile-- szybciej.
1
@potong masz rację, poprawione. @srikanthradix, chociaż może być szybsze, rozwiązaniem nie jest wyszukiwanie wyrażeń regularnych, ale tylko ustalonych ciągów. awk '{ if ( NR <= 10 ) { if( $0 ~ "YOUR_REGEXP") { print } } else { exit; } }' textfilerobi.
Zsolt Botykai
4
Poza tym styl nie jest awkish. 2xifsa 1xelsew poleceniu, które nie wymaga działania, stwierdzenie spowodowałoby aho. weinberger i kernighan płaczą ...
jaypal singh
1
Myślę, że zamiast NR lepiej byłoby użyć FNR, ponieważ jeśli używasz awk z wieloma plikami, FNR zaczyna się od 0 dla każdego pliku.
Vladyslav Savchenko
9

Masz kilka opcji używania programów wraz z grep. Najprostszym moim zdaniem jest użycie head:

head -n10 filename | grep ...

headwyświetli pierwsze 10 wierszy (używając -nopcji), a następnie możesz potokować to wyjście grep.

Dan Fego
źródło
6
Nie zdaje sobie sprawy, wszystkie rozwiązania wykorzystujące tutaj headzostały wykorzystane -n 10 (w tym mnie), nie zdając sobie sprawy, że headprzez standardowe wyświetlacze zaledwie 10 wierszy . :)
jaypal singh
4
grep "pattern" <(head -n 10 filename)
jaypal singh
źródło
3

Możesz użyć następującej linii:

head -n 10 /path/to/file | grep [...]
Gustavo Straube
źródło
3

Wyjście programu head -10 filemoże zostać przesłane potokiem grepw celu osiągnięcia tego:

head -10 file | grep 

Korzystanie z Perla:

perl -ne 'last if $. > 10; print if /pattern/' file
Alan Haggai Alavi
źródło
3
head -10 log.txt | grep -A 2 -B 2 pattern_to_search

-A 2: wypisz dwie linie przed wzorem.

-B 2: wypisz dwie linie po wzorze.

head -10 log.txt # read the first 10 lines of the file.
winnice
źródło
1
Jeśli dobrze pamiętam, -C 2zrobię to samo co-A 2 -B 2
David LeBauer
3
grep -m6 "string" cov.txt

To wyszukuje tylko pierwsze 6 wierszy string

Dileepa Chandima
źródło
3
Nie, to da ci pierwsze 6 wystąpień „string” w całym pliku
cov.txt
2

Rozszerzenie do odpowiedzi Joachima Isakssona: Dość często potrzebuję czegoś ze środka długiego pliku, np. Wiersze od 5001 do 5020, w takim przypadku można łączyć headz tail:

head -5020 file.txt | tail -20 | grep x

Spowoduje to pobranie pierwszych 5020 linii, a następnie wyświetlenie tylko ostatnich 20 z nich, a następnie potokuje wszystko do grep.

(Edytowano: błąd słupka ogrodzeniowego w moich przykładowych liczbach, dodano potok do grepa)

RoG
źródło
1

grep -A 10 <Wzór>

Ma to na celu pobranie wzoru i 10 następnych wierszy za wzorem. To działałoby dobrze tylko dla znanego wzorca, jeśli nie masz znanego wzorca, użyj sugestii „głowy”.

snowtop
źródło
1
Chociaż może to dobrze. dodaj więcej opisu pytania, aby odpowiedź była bardziej wyczerpująca.
Pramod S. Nikam
3
To odpowiada na zupełnie inne pytanie i nie jest przydatne w tym kontekście.
Pre101
-1

Miałem podobny problem i cały powyższy problem nie rozwiązuje go całkowicie. Interesuje mnie również uzyskanie nazwy pliku zawierającej pasujące wiersze. Moje rozwiązanie:

ls |parallel --gnu 'cat <(echo {}) <(head {})|grep -B1 -m1 -P "^>.*F3$"'

NB: Wzorzec w moim przypadku zawsze pasuje do pierwszej linii.

Shokrof
źródło