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! 🙂