Tubería de búsqueda en grep -v

Tubería de búsqueda en grep -v

Estoy tratando de encontrar todos los archivos que sean de un tipo determinado y que no contengan una cadena determinada. Estoy tratando de hacerlo canalizando find a grep -v

ejemplo:

find -type f -name '*.java' | xargs grep -v "something something"

Parece que esto no funciona. Parece estar devolviendo todos los archivos que encontró el comando de búsqueda. Lo que estoy tratando de hacer es básicamente encontrar todos los archivos .java que coincidan con un determinado nombre de archivo (por ejemplo, termine con 'Pb' como en SessionPb.java) y que no tengan un 'extiende AlgoAlgo' dentro.

Mi sospecha es que lo estoy haciendo mal. Entonces, ¿cómo debería verse el comando?

Respuesta1

No hay necesidad xargsaquí. También debe usar la opción grepwith -L(archivos sin coincidencia), porque de lo contrario generará el contenido del archivo en lugar de su nombre, como en su ejemplo.

find . -type f -iname "*.java" -exec grep -L "something somethin" {} \+

Respuesta2

Ya casi lo tienes realmente...

find . -type f -iname "*.java" -print0 | xargs -0 grep -v "something something"

El punto '.' dice empezar desde aquí. (el tuyo lo implica... pero nunca asumas).

-inameutiliza una búsqueda que no distingue entre mayúsculas y minúsculas, por si acaso (o simplemente sin mayúsculas y minúsculas).
-imprimir0envía nombres de archivos a xargs con un carácter final \x00, lo que evita problemas con los nombres de archivos que tienen espacios.

el '-0' en xargs dice que se esperan nombres de archivos que terminen en \x00 en lugar de devoluciones.

y tu comando grep...

Prácticamente lo entendí.


EDITAR::

De tu actualización:

find . -type f -iname "*pb.java" -print0 | xargs -0 grep -iL "something"

debería ayudar. (Se agregó -L de la respuesta de @rush, buen trabajo)

Tengo la idea de que su grep necesita la opción '-i' o ser menos explícito.

Pruebe el comando en partes... ¿ESTOS nombres de archivos de salida parecen adecuados?

find . -type f -iname "*pb.java"

Si es así, entonces su problema probablemente sea que su patrón de búsqueda grep no coincide (¿error de ortografía? ¡Sucede!), o simplemente no hay coincidencias.

El peor caso absoluto:

grep -riL "something" *

Hará MUCHO más trabajo buscando todo, pero debería brindarle algunos resultados.

Respuesta3

La computadora es una computadora: hace lo que le dijiste que hiciera en lugar de lo que tú querías que hiciera.

grep -v "something something"imprime todas las líneas que no contienen something something. Por ejemplo, imprime dos líneas entre las tres siguientes:

hello world
this is something something
something else

Para imprimir archivos que no contienen extends SomethingSomethingningún lugar, use la -Lopción:

grep -L -E 'extends[[:space:]]+SomethingSomething' FILENAME…

Algunas versiones de grep no tienen la -Lopción (no está especificada porPOSIX). Si el suyo no lo hace, haga que no imprima nada y use el código de retorno para que el shell que llama haga lo que debe hacer en su lugar.

grep -q -E 'extends[[:space:]]+SomethingSomething' FILENAME ||
echo "$FILENAME"

Alternativamente, use awk.

awk '
    FNR == 1 && NR != 1 && !found { print fn }
    FNR == 1 { fn = FILENAME; found = 0; }
    /extends[[:space:]]+SomethingSomething/ { found = 1 }
    END { if (fn != "" && !found) print fn }
'

En Linux o Cygwin (u otro sistema con GNU grep), no es necesario utilizar find, ya grepque es capaz de recurrir.

grep -R --include='*.java' -L -E 'extends[[:space:]]+SomethingSomething'

Si su shell es ksh, bash o zsh, puede hacer que el shell coincida con el nombre del archivo. En bash, ejecuta set -o globstarprimero (puedes poner esto en tu ~/.bashrc).

grep -L -E 'extends[[:space:]]+SomethingSomething' **/*.java

Respuesta4

find -type f -name '*.java' 2>&1 | grep -v "something something"

lo que está "obteniendo" se muestra en stderr, no en stdout.

el comando anterior redirige stderr a stdout

Fuente

información relacionada