
Considere los siguientes archivos:
$ find findtest
findtest
findtest/test1
findtest/test1/start.ksh
findtest/test2
findtest/test2/start.ksh
findtest/test3
findtest/test3/start.ksh
findtest/test4
findtest/test4/start.ksh
Mi pregunta es sobre el uso de {}
en la -exec
llamada. Funciona como lo esperaría al designar el archivo de resultados:
$ find findtest -name test[1-4] -exec ls -d {} \;
findtest/test1
findtest/test2
findtest/test3
findtest/test4
Sin embargo, no parece expandirse cuando se usa en una ruta:
$ find findtest -name test[1-4] -exec md5sum {}/start.ksh \;
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
¿Cómo puedo utilizar find -type d -exec
para acceder a archivos de jerarquía inferior? Sé que puedo usar un for
bucle como este, pero tengo curiosidad por saber si se puede hacer en una sola find
llamada:
$ for f in $(find findtest -name test[1-4]); do md5sum "$f"/start.ksh; done
d41d8cd98f00b204e9800998ecf8427e findtest/test1/start.ksh
d41d8cd98f00b204e9800998ecf8427e findtest/test2/start.ksh
d41d8cd98f00b204e9800998ecf8427e findtest/test3/start.ksh
d41d8cd98f00b204e9800998ecf8427e findtest/test4/start.ksh
Respuesta1
ElEstándar POSIX para el comando de búsquedasolo exige que un {} aislado sea reemplazado por el nombre del archivo, y solo el primero. El uso {}/start.ksh
conduce a un comportamiento no especificado.
Un argumento que contenga sólo los dos caracteres "{}" será reemplazado por el conjunto de nombres de ruta agregados, y cada nombre de ruta se pasará como un argumento separado a la utilidad invocada en el mismo orden en que se agregó. El tamaño de cualquier conjunto de dos o más nombres de ruta se limitará de manera que la ejecución de la utilidad no provoque que se exceda el límite {ARG_MAX} del sistema. Si hay más de un argumento que contiene sólo los dos caracteres "{}", el comportamiento no se especifica.
Si un nombre_utilidad o una cadena de argumento contiene los dos caracteres "{}", pero no solo los dos caracteres "{}", la implementación define si find reemplaza esos dos caracteres o usa la cadena sin cambios.
Una forma de hacer lo que quieres con Solaris find sería ese comando:
find findtest -name "test[1-4]" -exec sh -c 'md5sum $1/start.ksh' foo {} \;
Una forma más rápida sería:
find findtest -name "test[1-4]" -exec sh -c 'for i; do md5sum "$i/start.ksh"; done' foo {} +
Respuesta2
- En realidad, su shell se está expandiendo
test[1-4]
antes de invocarfind
. Necesitas escapar con'…'
{}
se trata como patrón solo cuando es un token separado
-exec
En sí mismo suele ser costoso y se recomienda usarlo con el arrastre +
o evitarlo en favor de la alimentación xargs
.
Sé que puedo usar un bucle for como este, pero tengo curiosidad por saber si se puede hacer en una llamada de búsqueda:
find findtest -name 'test[1-4]' -print0 | xargs -0I{} -- md5sum '{}/start.ksh'
- se ejecuta md5sum
eficientemente - con todos los nombres de archivos proporcionados a la vez.