bash trouver xargs grep seule occurrence unique

16

C'est peut-être un peu étrange - et il y a peut-être d'autres outils pour le faire, mais bon ...

J'utilise la commande bash classique suivante pour trouver tous les fichiers contenant une chaîne:

find . -type f | xargs grep "something"

J'ai un grand nombre de fichiers, sur plusieurs profondeurs. la première occurrence de "quelque chose" me suffit, mais la recherche continue et prend beaucoup de temps pour terminer le reste des fichiers. Ce que je voudrais faire, c'est quelque chose comme une "rétroaction" de grep pour trouver afin que find puisse arrêter de rechercher plus de fichiers. Une telle chose est possible?

bonjour_earth
la source

Réponses:

20

Gardez-le simplement dans le domaine de la recherche:

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

Voilà comment cela fonctionne:

Le -execfonctionnera quand le -type fsera vrai. Et parce que grepretourne 0(succès / vrai) lorsque le -exec grep "something"a une correspondance, le -quitsera déclenché.

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

fait exactement cela: lorsque la headterminaison, l'élément central du tuyau est notifié avec un signal de «rupture de tuyau», se termine à son tour et notifie le find. Vous devriez voir un avis tel que

xargs: grep: terminated by signal 13

ce qui confirme cela.

Kilian Foth
la source
+1 pour l'explication et l'alternative, bien que l'autre réponse me semble plus élégante, car elle est plus autosuffisante
hello_earth
8

Pour ce faire sans changer d'outils: (j'adore les 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
la source
1
+1 n'a jamais su que les xargs auraient de telles capacités multitâches - merci aussi pour les autres commentaires! :)
hello_earth