bash znajduje xargs grep tylko raz

16

Może to trochę dziwne - a może są do tego inne narzędzia, ale ...

Korzystam z następującego klasycznego polecenia bash, aby znaleźć wszystkie pliki zawierające ciąg znaków:

find . -type f | xargs grep "something"

Mam dużą liczbę plików na wielu głębokościach. pierwsze wystąpienie „czegoś” jest dla mnie wystarczające, ale szukanie kontynuuje wyszukiwanie i zajmuje dużo czasu, aby uzupełnić resztę plików. To, co chciałbym zrobić, to coś w rodzaju „sprzężenia zwrotnego” z grep z powrotem do znalezienia, aby find mógł przestać szukać więcej plików. Czy coś takiego jest możliwe?

hello_earth
źródło

Odpowiedzi:

20

Po prostu trzymaj to w sferze Find:

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

Tak to działa:

-execBędzie działać, gdy -type fbędzie prawdziwe. A ponieważ grepzwraca 0(sukces / prawda), gdy -exec grep "something"dopasowanie jest dopasowane, -quitzostanie ono uruchomione.

Chen Levy
źródło
8
find -type f | xargs grep e | head -1

robi dokładnie to: kiedy headkończy się, środkowy element rury jest powiadamiany sygnałem „zepsutej rury”, z kolei kończy się i powiadamia o tym find. Powinieneś zobaczyć powiadomienie, takie jak

xargs: grep: terminated by signal 13

co to potwierdza.

Kilian Foth
źródło
+1 za wyjaśnienie i alternatywę, choć druga odpowiedź wydaje mi się bardziej elegancka, ponieważ jest bardziej samowystarczalna
hello_earth 16.01.2013
8

Aby to zrobić bez zmiany narzędzi: (Kocham 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
bukzor
źródło
1
+1 nigdy nie wiedziałem, że xargs będzie miał takie możliwości wielozadaniowości - dziękuję również za inne komentarze! :)
hello_earth