Usar la salida de ls
para obtener nombres de archivos es una mala idea. Puede conducir a un mal funcionamiento e incluso a guiones peligrosos. Esto se debe a que un nombre de archivo puede contener cualquier carácter excepto /
y el carácter null
, y ls
no utiliza ninguno de esos caracteres como delimitadores, por lo que si un nombre de archivo tiene un espacio o una nueva línea, _obtendrá resultados inesperados.
Hay dos formas muy buenas de iterar sobre los archivos. Aquí, he usado simplemente echo
para demostrar cómo hacer algo con el nombre de archivo; puedes usar cualquier cosa, sin embargo.
La primera es usar las características nativas de globbing de la shell.
for dir in */; do
echo "$dir"
done
El shell expande */
en argumentos separados que el bucle for
lee; incluso si hay un espacio, una nueva línea o cualquier otro carácter extraño en el nombre de archivo, for
verá cada nombre completo como una unidad atómica; no está analizando la lista de ninguna manera.
Si quieres ir de forma recursiva a subdirectorios, entonces esto no servirá a menos que tu shell tenga algunas características de globbing extendidas (como las de bash
globstar
. Si tu shell no tiene estas características, o si quieres asegurarte de que tu script funcionará en una variedad de sistemas, entonces la siguiente opción es usar find
.
find . -type d -exec echo '{}' \;
Aquí, el comando find
llamará a echo
y le pasará un argumento del nombre de archivo. Lo hace una vez por cada archivo que encuentra. Al igual que en el ejemplo anterior, no hay análisis sintáctico de una lista de nombres de archivos; en su lugar, se envía un nombre de archivo completamente como un argumento.
La sintaxis del argumento -exec
tiene un aspecto un poco extraño. find
toma el primer argumento después de -exec
y lo trata como el programa a ejecutar, y cada argumento posterior, lo toma como un argumento a pasar a ese programa. Hay dos argumentos especiales que -exec
necesita ver. El primero es {}
; este argumento es reemplazado por un nombre de archivo que las partes anteriores de find
generan. El segundo es ;
, que permite a find
saber que éste es el final de la lista de argumentos que hay que pasar al programa; find
necesita esto porque puedes continuar con más argumentos que están destinados a find
y que no están destinados al programa ejecutado. La razón de [Usar la salida de
lspara obtener nombres de archivos es una mala idea] &003. Puede conducir a un mal funcionamiento e incluso a guiones peligrosos. Esto se debe a que un nombre de archivo puede contener cualquier carácter excepto
/y el carácter
null, y
ls` no utiliza ninguno de esos caracteres como delimitadores, por lo que si un nombre de archivo tiene un espacio o una nueva línea, _obtendrá resultados inesperados.
Hay dos formas muy buenas de iterar sobre los archivos. Aquí, he usado simplemente echo
para demostrar cómo hacer algo con el nombre de archivo; puedes usar cualquier cosa, sin embargo.
La primera es usar las características nativas de globbing de la shell.
for dir in */; do
echo "$dir"
done
El shell expande */
en argumentos separados que el bucle for
lee; incluso si hay un espacio, una nueva línea o cualquier otro carácter extraño en el nombre de archivo, for
verá cada nombre completo como una unidad atómica; no está analizando la lista de ninguna manera.
Si quieres ir de forma recursiva a subdirectorios, entonces esto no servirá a menos que tu shell tenga algunas características de globbing extendidas (como las de bash
globstar
. Si tu shell no tiene estas características, o si quieres asegurarte de que tu script funcionará en una variedad de sistemas, entonces la siguiente opción es usar find
.
find . -type d -exec echo '{}' \;
Aquí, el comando find
llamará a echo
y le pasará un argumento del nombre de archivo. Lo hace una vez por cada archivo que encuentra. Al igual que en el ejemplo anterior, no hay análisis sintáctico de una lista de nombres de archivos; en su lugar, se envía un nombre de archivo completamente como un argumento.
La sintaxis del argumento -exec
tiene un aspecto un poco extraño. find
toma el primer argumento después de -exec
y lo trata como el programa a ejecutar, y cada argumento posterior, lo toma como un argumento a pasar a ese programa. Hay dos argumentos especiales que -exec
necesita ver. El primero es {}
; este argumento es reemplazado por un nombre de archivo que las partes anteriores de find
generan. El segundo es ;
, que permite a find
saber que éste es el final de la lista de argumentos que hay que pasar al programa; find
necesita esto porque puedes continuar con más argumentos que están destinados a find
y que no están destinados al programa ejecutado. La razón de es que la shell también trata ;
de forma especial - representa el final de un comando, por lo que necesitamos escapar de él para que la shell lo dé como argumento a find
en lugar de consumirlo por sí mismo; otra forma de conseguir que la shell no lo trate de forma especial es ponerlo entre comillas: ';'
funciona igual de bien que \;
para este propósito.