2012-12-30 12 views
155

Przeszukuję katalog rekursywnie używając grep z następującymi argumentami mając nadzieję, że tylko zwrócę pierwsze dopasowanie. Niestety, zwraca więcej niż jeden - w rzeczywistości dwa, gdy ostatnio patrzyłem. Wygląda na to, że mam zbyt wiele argumentów, zwłaszcza bez uzyskania pożądanego rezultatu. : -/Grep tylko pierwszy mecz i zatrzymaj się

# grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/directory 

powraca:

Pulsanti Operietur 
Pulsanti Operietur 

Może grep nie jest najlepszym sposobem, aby to zrobić? Powiedz mi, dziękuję bardzo.

Odpowiedz

262

-m 1 oznacza powrót pierwszego dopasowania w danym pliku. Ale nadal będzie wyszukiwał inne pliki. Ponadto, jeśli są dwa lub więcej pasujących do tej samej linii, wszystkie zostaną wyświetlone.

Można użyć head -1 aby rozwiązać ten problem:

grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -1 
+0

niesamowite! Dziękuję Ci. btw - czy wszystkie pozostałe argumenty są niezbędne w rozkazie? a jeśli nie mogę tego zrobić przypadkowo (na wszelki wypadek). –

+2

Nie sądzę, że są one konieczne (z wyjątkiem oczywiście '-r'), ale nie powinny boleć (nie używałbym' -a' chociaż) – mvp

+1

Dokładnie to, czego potrzebowałem. Mój wzorzec został znaleziony dwa razy w tej samej linii, a 'grep -m 1' zwrócił oba wystąpienia z tego powodu. '| head -1' rozwiązało to! – harperville

12

grep-a-like Program ack ma -1 opcję, która zatrzymuje się na pierwszy mecz nigdzie. Obsługuje on kod -m 1, do którego odnosi się także adres @mvp. Umieszczam to tam, ponieważ jeśli szukam dużego drzewa kodu źródłowego, aby znaleźć coś, co wiem, że istnieje w jednym pliku, nie trzeba go znaleźć i trzeba nacisnąć Ctrl-C.

+0

, więc można powiedzieć, że ack jest szybszy niż grep?Naprawdę martwię się również współczynnikiem prędkości. –

+0

ack może być szybszy niż grep, w zależności od tego, czego szukasz. Należy pamiętać, że ack dotyczy wyszukiwania kodu źródłowego. Jeśli szukasz ogólnych plików, jest w tym mniej dobra, przynajmniej w pliku potwierdzenia 1.x. Idź przeczytać o ack i sprawdź, czy może pasuje do twoich potrzeb. –

+2

Używam Ack przez długi czas, ale ostatnio przełączyłem się na [srebrny poszukiwacz] (https://github.com/ggreer/the_silver_searcher), który uważam za szybszy Ack –

4

pojedynczą warstwę, wykorzystując find:

find -type f -exec grep -lm1 "PATTERN" {} \; -a -quit 
+4

To będzie * bardzo * wolno, ponieważ find odrodzi kopię grep dla każdego znalezionego pliku. 'grep -r' działa o wiele szybciej - jest to jedyna kopia, która przechwytuje katalogi. – mvp

+0

Prawda; choć find można dostosować tak, by działał tylko na filtrowanych wynikach, co może uczynić operację znacznie szybszą niż catch-all grep. Zależy od kontekstu. –

13

można przepuścić grep znalezione head w połączeniu z stdbuf.

Zauważ, że w celu zapewnienia zatrzymanie po N-tego meczu, trzeba za pomocą stdbuf aby upewnić grep nie bufor swoje wyjście:

stdbuf -oL grep -rl 'pattern' * | head -n1 
stdbuf -oL grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -n1 
stdbuf -oL grep -nH -m 1 -R "django.conf.urls.defaults" * | head -n1 

Jak tylko head zużywa 1 linia, to zakończone i grep otrzyma SIGPIPE, ponieważ nadal wysyła coś do potoku, gdy zniknęła head.

Założono, że żadne nazwy plików nie zawierają nowej linii.