A veces veo el siguiente comando:
find . -name * -exec ls -a {} \;
Me pidieron que ejecutara esto.
¿Qué {} \;
significa aquí?
fuente
A veces veo el siguiente comando:
find . -name * -exec ls -a {} \;
Me pidieron que ejecutara esto.
¿Qué {} \;
significa aquí?
Si ejecuta find
con exec
, se {}
expande al nombre de archivo de cada archivo o directorio encontrado con find
(para que ls
en su ejemplo obtenga cada nombre de archivo encontrado como argumento; tenga en cuenta que llama ls
o cualquier otro comando que especifique una vez para cada archivo encontrado).
Semicolon ;
finaliza el comando ejecutado por exec
. Debe escaparse \
para que el shell que ejecuta en su find
interior no lo trate como su propio carácter especial, sino que se lo pase find
.
Vea este artículo para más detalles.
Además, find
proporciona cierta optimización con exec cmd {} +
: cuando se ejecuta así, find
agrega los archivos encontrados al final del comando en lugar de invocarlo una vez por archivo (de modo que el comando se ejecuta solo una vez, si es posible).
La diferencia en el comportamiento (si no es en eficiencia) se nota fácilmente si se ejecuta con ls
, p. Ej.
find ~ -iname '*.jpg' -exec ls {} \;
# vs
find ~ -iname '*.jpg' -exec ls {} +
Suponiendo que tiene algunos jpg
archivos (con rutas lo suficientemente cortas ), el resultado es una línea por archivo en el primer caso y el ls
comportamiento estándar de mostrar archivos en columnas para el último.
\;
con +
.
find . -name * | ls -a -
?
find
. Además, la salida de ls
en este caso aparentemente no depende de la entrada; no importa lo que use como filtro find
, ls
solo muestra el contenido del directorio de trabajo y eso es todo. Compruebe por ejemplo find ~ -iname '*.jpg' -exec ls -a {} \;
vs find ~ -iname '*.jpg' | ls -a
.
echo 'foo' | ls -a
.
-
en tu ls -a -
comando al probar lo que @ dr-h preguntó.
Desde la página de manual para el find
comando :
-exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to
the command until an argument consisting of `;' is encountered. The string `{}' is replaced by the current
file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it
is alone, as in some versions of find. Both of these constructions might need to be escaped (with a `\') or
quoted to protect them from expansion by the shell.
Así que aquí está la explicación:
{}
significa "la salida de find
". Como en "lo que sea que se find
encuentre". find
devuelve la ruta del archivo que estás buscando, ¿verdad? Entonces lo {}
reemplaza; es un marcador de posición para cada archivo que find
localiza el comando (tomado de aquí ).
La \;
parte básicamente dice find
"está bien, he terminado con el comando que quería ejecutar".
Digamos que estoy en un directorio lleno de .txt
archivos. Entonces corro:
find . -name '*.txt' -exec cat {} \;
La primera parte, find . -name *.txt
devuelve una lista de los .txt
archivos. La segunda parte, -exec cat {} \;
ejecutará el cat
comando para cada archivo encontrado por find
, por lo que cat file1.txt
, cat file2.txt
y así sucesivamente.
*.txt
debe ser citada como '*.txt'
. Esto se debe a que si hay .txt
archivos en la carpeta actual, el shell expandirá esto y obtendrá resultados incorrectos o un mensaje de error. find -name '*.txt' -exec cat {} \;
-name *
es redundante-name *
Es peor que redundante. Debido a*
que no está entre comillas, el shell lo expande a la lista de nombres de archivo en la carpeta actual, con espacios que se tratan incorrectamente, lo que genera resultados inesperados o un mensaje de error. Como punto extra,find
tiene muchas funciones, una de ellas es listar archivos; Esto evita tener que usar-exec
. Por ejemplo, puedes usarfind . -print
ofind . -ls
. Por último, hay dos maneras de escapar del punto y coma: o bien como lo hizo con la barra invertida,\;
o por citar:';'
. Use el que le resulte más cómodo.