Może to trochę dziwne – i może są inne narzędzia do tego, ale cóż …

Używam następującego klasycznego polecenia bash, aby znaleźć wszystkie pliki zawierające jakiś ciąg:

find . -type f | xargs grep "something" 

Mam dużą liczbę plików na różnych głębokościach . pierwsze wystąpienie „czegoś” jest dla mnie wystarczające, ale find kontynuuje wyszukiwanie, a uzupełnienie pozostałych plików zajmuje dużo czasu. Chciałbym uzyskać coś w rodzaju „opinii” od grepa, aby znaleźć, aby find może przestać wyszukiwać więcej plików. Czy coś takiego jest możliwe?

Odpowiedź

Po prostu utrzymuj to w obszarze find:

find . -type f -exec grep "something" {} \; -quit 

Tak to działa:

-exec będzie działać, gdy -type f będzie prawdziwe. A ponieważ grep zwraca 0 (sukces / prawda), gdy pasuje, zostanie wywołana -quit.

Odpowiedź

find -type f | xargs grep e | head -1 

robi dokładnie to: kiedy head kończy działanie, środkowy element potoku jest powiadamiany o„ pękniętej potoku „, kończy się po kolei i powiadamia find. Powinieneś zobaczyć powiadomienie, takie jak

xargs: grep: terminated by signal 13 

, które to potwierdza.

Komentarze

  • +1 dla wyjaśnienia i alternatywy, chociaż druga odpowiedź wydaje mi się bardziej elegancka, ponieważ jest bardziej samowystarczalna

Odpowiedź

Aby to zrobić bez zmiany narzędzi: (uwielbiam xargs)

#!/bin/bash find . -type f | # xargs -n20 -P20: use 10 parallel processes to grep files in batches of 20 # grep -m1: show just on match per file # grep --line-buffered: multiple matches from independent grep processes # will not be interleaved xargs -P10 -n20 grep -m1 --line-buffered "$1" 2> >( # Error output (stderr) is redirected to this command. # We ignore this particular error, and send any others back to stderr. grep -v "^xargs: .*: terminated by signal 13$" >&2 ) | # Little known fact: all `head` does is send signal 13 after n lines. head -n 1 

Komentarze

  • +1 nigdy nie wiedziałem, że xargs będzie miał takie możliwości wielozadaniowości – dziękuję również za inne komentarze! 🙂

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *