bash find xargs grep nur einmal vorkommen

16

Vielleicht ist es ein bisschen seltsam - und vielleicht gibt es andere Werkzeuge, um dies zu tun, aber nun ...

Ich benutze den folgenden klassischen Bash-Befehl, um alle Dateien zu finden, die eine Zeichenfolge enthalten:

find . -type f | xargs grep "something"

Ich habe eine große Anzahl von Dateien in mehreren Tiefen. Das erste Auftreten von "etwas" ist für mich ausreichend, aber find sucht weiter und es dauert lange, bis der Rest der Dateien fertig ist. Was ich tun möchte, ist so etwas wie ein "Feedback" von grep back zu finden, so dass find aufhören könnte, nach mehr Dateien zu suchen. Ist so etwas möglich?

hallo_erde
quelle

Antworten:

20

Halten Sie es einfach im Bereich der Suche:

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

So funktioniert es:

Der -execWille funktioniert, wenn der -type fWille wahr ist. Und weil grepRenditen 0(Erfolg / true) , wenn das -exec grep "something"ein Spiel ist, das -quitausgelöst.

Chen Levy
quelle
8
find -type f | xargs grep e | head -1

genau das tut: wenn der headterminiert, wird das mittlere Element der Pipe mit einem 'broken pipe'-Signal benachrichtigt, endet der Reihe nach und benachrichtigt den find. Sie sollten einen Hinweis wie sehen

xargs: grep: terminated by signal 13

was dies bestätigt.

Kilian Foth
quelle
+1 für die Erklärung und die Alternative, obwohl die andere Antwort mir eleganter erscheint, da es autarker ist
hallo_earth
8

Um dies zu tun, ohne das Werkzeug zu wechseln: (Ich liebe 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
quelle
1
+1 Ich hätte nie gedacht, dass Xargs solche Multitasking-Fähigkeiten haben würden - danke auch für andere Kommentare! :)
hello_earth