2011-02-04 23 views
9

En un script bash, quiero iterar sobre todos los directorios en el directorio de trabajo actual y hacerles cosas. Pueden contener símbolos especiales, especialmente espacios en blanco. ¿Cómo puedo hacer eso? Tengo:Bucle en directorios con espacios en blanco en Bash

for dir in $(ls -l ./) 
do 
    if [ -d ./"$dir" ] 

pero esto omite mis directorios con espacios en blanco en su nombre. Cualquier ayuda es apreciada.

Respuesta

24

seguirlo:

for dir in */ 
+0

esto lo hace, pero ¿por qué? */es un comodín para todos los directorios? – jakev

+1

Guau, eso realmente funciona, incluso en directorios con espacios. Entonces, ¿bash debe citar implícitamente los valores cuando expande el comodín? Lo amo. – harpo

+0

@JakeVA: Sí, exactamente. Tenga en cuenta que no incluirá directorios ocultos a menos que configure 'shopt -s dotglob'. Si el directorio actual puede no tener subdirectorios, también debe establecer 'shopt -s nullglob' (configúrelo por si acaso). –

8

una serie de opciones de soluciones:

http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html

La idea general es cambiar el separador predeterminado (IFS).

#!/bin/bash 
SAVEIFS=$IFS 
IFS=$(echo -en "\n\b") 
for f in * 
do 
    echo "$f" 
done 
IFS=$SAVEIFS 
+0

Me olvidé de mencionar esto en mi pregunta, pero lo intenté. Creo que la pieza faltante se repetía sobre * o */en lugar de los resultados de ls – jakev

+0

Encontré mi solución aquí, usando 'find. -print0 | while read -d $ '\ 0' file' para configurar un bucle 'do' con la variable' file'. – Air

3

Existen varias formas. Aquí hay algo que es muy rápido:

find /your/dir -type d -print0 | xargs -0 echo 

Esto escaneará/tu/dir para directorios de forma recursiva y pasará todos los caminos para el comando "echo" (cambio de su necesidad). Puede invocar echo varias veces, pero intentará pasar tantos nombres de directorio como la consola permita a la vez. Esto es extremadamente rápido porque es necesario iniciar pocos procesos. Pero solo funciona en programas que pueden tomar una cantidad arbitraria de valores como opciones. -print0 dice a encontrar rutas de archivos separados usando un byte cero (y -0 dice xargs para leer argumentos separados por cero bytes) Si usted no tiene la posterior, se puede hacer esto:

find /your/dir -type d -print0 | xargs -0 -n 1 echo 

o

find /your/dir -type d -print0 --exec echo '{}' ';' 

La opción -n le dirá a xargs que no pase más argumentos que uno al mismo tiempo a su programa. Si no desea buscar para buscar recursivamente, puede especificar la opción de profundidad para deshabilitar la recursión (sin embargo, no sé la sintaxis de memoria).

Aunque si eso es útil en su script particular es otra pregunta ;-).

+0

Tenga en cuenta que xargs tiene herramientas adicionales que son útiles aquí, como -J . Ejemplo: xargs -0 -J% mv% ~/some_other_folder –

Cuestiones relacionadas