¿Cómo detectar si "find" encontró alguna coincidencia?

16

¿Hay algún medio idiomático para detectar si "find" encontró alguna coincidencia? Actualmente estoy usando

COUNT=`find ... | wc -l`
if [ "$COUNT" -gt 0 ]; then

pero esto me parece un poco indirecto. Además, me gustaría que dejara de buscar una vez que haya encontrado una coincidencia, para que no pierda tiempo y esfuerzo. Solo necesito saber si hay archivos que coincidan o no.

Actualización: cometí el error de escribir mi pregunta sin el código que tenía delante: lo uso wc -len un caso diferente, donde necesito saber el número total de archivos encontrados de todos modos. En el caso donde solo estoy probando si hay coincidencias, estaba usando if [ -z $(find …) ].

Chris Page
fuente

Respuestas:

17

Si sabe que tiene GNU find, utilícelo -quit para detenerlo después de la primera coincidencia.

Portablemente, canalice la salida de finden head -n 1. De esa manera find, morirá una tubería rota después de algunas coincidencias (cuando se llena headel búfer de entrada).

De cualquier manera, no necesita wcprobar si una cadena está vacía, el shell puede hacerlo por sí solo.

if [ -n "$(find … | head -n 1)" ]; then …
Gilles 'SO- deja de ser malvado'
fuente
Interesante ... pensé que -nsolo se aplicaba a variables 'definidas' ($ abc, $ xyz, etc.), pero supongo que $ (...) es una variable temporal 'definida' ... +1 ... (y simplemente lea recientemente que usar -nes arriesgado, a menos que esté seguro de que la variable aún no se ha declarado y está 'sin usar) ... pero una temperatura no tendrá esta posibilidad ... es decir. sin inicializar vs vacío
Peter
2
@fred: Por el contrario, -nprueba si una cadena está vacía, no tiene nada que ver con las variables. Lo que has leído probablemente decía que usar -nno prueba si una variable está definida: -n "$foo"es falsa si fooestá definida pero está vacía, y muestra un mensaje de error debajo set -u. [ -n "${foo+1}" ]prueba de manera confiable si fooestá configurado, pero tratar variables vacías y no configuradas de manera idéntica suele ser una buena idea [ -n "${foo:+1}" ], o simplemente [ -n "$foo" ]si no le preocupa set -u.
Gilles 'SO- deja de ser malvado'
¡Gracias! No tengo -quitdisponible, pero la tubería head -n 1funciona (como lo hace head -c 1, lo que se detiene incluso antes, pero probablemente con un beneficio insignificante). Además, cometí el error de escribir mi pregunta sin el código que tenía delante: lo uso wc -len un caso diferente, donde necesito saber la cantidad total de archivos encontrados. En el caso donde solo estoy probando si hay coincidencias, estaba usando if [ -z `find … ` ].
Chris Page
6

Puedes usar la -quitacción para detenerte después del primer partido. Probablemente desee combinar eso con otra acción (como -print) o no podrá saber si encontró algo.

Por ejemplo, find ... -print -quitimprimirá la ruta del primer archivo coincidente y luego saldrá. O bien, puede usar -printf 1 -quitpara imprimir 1 si hay una coincidencia y nada si no la hay.

findEl estado de salida refleja si hubo errores durante la búsqueda y no si encontró algo, por lo que debe verificar su salida para ver si hay una coincidencia.

cjm
fuente
-quites una extensión de GNU. No funcionará en sistemas que usan otras implementaciones de find (1), como OS X, los BSD y probablemente la mayoría de los Unices comerciales.
Warren Young
Gracias, es útil saberlo en caso de que esté usando otro sistema. Desafortunadamente, ni -quit ni -printf están disponibles en el mío (Mac OS X).
Chris Page
4

La salida 0 es fácil con find, la salida> 0 es más difícil porque eso generalmente solo ocurre con un error. Sin embargo, podemos hacer que suceda:

if find -type f -exec false {} +
then
  echo 'nothing found'
else
  echo 'something found'
fi

Tenga en cuenta que esta solución es más eficaz que usar una subshell; ejecutar falso es ciertamente más rápido que ejecutar incluso Dash:

$ cat alfa.sh bravo.sh charlie.sh delta.sh
find -name non-existing-file -exec false {} +
find -name existing-file -exec false {} +
[ "$(find -name non-existing-file)" ]
[ "$(find -name existing-file)" ]

$ strace dash alfa.sh | wc -l
807

$ strace dash bravo.sh | wc -l
1141

$ strace dash charlie.sh | wc -l
1184

$ strace dash delta.sh | wc -l
1194
Steven Penny
fuente
0

Puede envolverlo en la condición de shell, por ejemplo:

[ "$(find . ...)" '!=' '' ] && echo Found || echo Not found

¿Dónde ...está su condición de partido, por ejemplo -name *.txt.

Algunos otros ejemplos:

[ "$(find /etc -name hosts)" ] && echo True || echo False
[ ! -z "$(find /etc -name hosts)" ] && echo True || echo False
kenorb
fuente