bash find xargs grep solo una vez

16

Tal vez sea un poco extraño, y tal vez haya otras herramientas para hacer esto, pero bueno ...

Estoy usando el siguiente comando bash clásico para encontrar todos los archivos que contienen alguna cadena:

find . -type f | xargs grep "something"

Tengo una gran cantidad de archivos, en múltiples profundidades. la primera aparición de "algo" es suficiente para mí, pero find continúa buscando y lleva mucho tiempo completar el resto de los archivos. Lo que me gustaría hacer es algo así como un "comentario" de grep back to find para que find pueda dejar de buscar más archivos. ¿Es posible tal cosa?

hola_ tierra
fuente

Respuestas:

20

Simplemente manténgalo dentro del ámbito de encontrar:

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

Así es como funciona:

El -execfuncionará cuando el -type fva a ser verdad. Y debido a que grepregresa 0(éxito / verdadero) cuando -exec grep "something"tiene una coincidencia, -quitse activará.

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

hace exactamente eso: cuando headtermina, el elemento central de la tubería se notifica con una señal de 'tubería rota', termina a su vez y notifica a la find. Debería ver un aviso como

xargs: grep: terminated by signal 13

lo cual confirma esto.

Kilian Foth
fuente
+1 para la explicación y la alternativa, aunque la otra respuesta me parece más elegante, ya que es más autosuficiente
hello_earth
8

Para hacer esto sin cambiar las herramientas: (Me encanta 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
fuente
1
+1 nunca supo que los xargs tendrían capacidades multitarea, ¡gracias por otros comentarios también! :)
hello_earth