Respuestas:
Puede especificar una barra diagonal al final para que coincida solo con los directorios:
for d in */ ; do
echo "$d"
done
[[ -L $d ]]
si $ d es un enlace simbólico.
set -P
solo afecta a los comandos que cambian de directorio. sprunge.us/TNac
[[ -L "$f" ]]
no excluirá los enlaces simbólicos en este caso con */
, debe quitar la barra inclinada final [[ -L "${f%/}" ]]
(vea Prueba para el enlace con la barra inclinada final )
Puedes probar con -d
:
for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
Este es uno de los operadores de prueba de archivos .
if [[ -d "$f" && ! -L "$f" ]]
excluirá enlaces simbólicos
if [[ "$f" = "*" ]]; then continue; fi
Tenga en cuenta que la solución de choroba, aunque elegante, puede provocar un comportamiento inesperado si no hay directorios disponibles dentro del directorio actual. En este estado, en lugar de omitir el for
ciclo, bash ejecutará el ciclo exactamente una vez donde d
es igual a */
:
#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo $d
done
Recomiendo usar lo siguiente para protegerse contra este caso:
#!/usr/bin/env bash
for f in *; do
if [ -d ${f} ]; then
# Will not run if no directories are available
echo $f
fi
done
Este código recorrerá todos los archivos en el directorio actual, verificará si f
es un directorio, luego hará eco f
si la condición devuelve verdadero. Si f
es igual a */
, echo $f
no se ejecutará.
shopt -s nullglob
.
Si necesita seleccionar archivos más específicos que solo los directorios usan find
y pasarlos a while read
:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Se usa shopt -u dotglob
para excluir directorios ocultos (o setopt dotglob
/ unsetopt dotglob
en zsh).
IFS=
para evitar dividir nombres de archivo que contengan uno de los siguientes $IFS
, por ejemplo:'a b'
vea la respuesta de AsymLabs a continuación para más find
opciones
editar:
en caso de que necesite crear un valor de salida desde el ciclo while, puede eludir la subshell adicional con este truco:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
Puedes usar pure bash para eso, pero es mejor usar find:
find . -maxdepth 1 -type d -exec echo {} \;
(Encontrar adicionalmente incluirá directorios ocultos)
shopt -s dotglob
para bash
incluir directorios ocultos. El tuyo también incluirá .
. También tenga en cuenta que -maxdepth
no es una opción estándar ( -prune
es).
dotglob
opción es interesante pero dotglob
solo se aplica al uso de *
. find .
siempre incluirá directorios ocultos (y el directorio actual también)
Esto se hace para encontrar directorios visibles y ocultos dentro del directorio de trabajo actual, excluyendo el directorio raíz:
simplemente recorrer los directorios:
find -path './*' -prune -type d
para incluir enlaces simbólicos en el resultado:
find -L -path './*' -prune -type d
hacer algo a cada directorio (excluyendo enlaces simbólicos):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
para excluir directorios ocultos:
find -path './[^.]*' -prune -type d
para ejecutar múltiples comandos en los valores devueltos (un ejemplo muy artificial):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '{}' sh -c \
"printf 'first: %-40s' '{}'; printf 'second: %s\n' '{}'"
en lugar de 'sh -c' también puede usar 'bash -c', etc.
... -print0 | xargs -0 ...
si no sabe cuáles son los nombres exactos.
find * | while read file; do ...
Puede recorrer todos los directorios, incluidos los directorios ocultos (comenzando con un punto) en una línea y múltiples comandos con:
for file in */ .*/ ; do echo "$file is a directory"; done
Si desea excluir enlaces simbólicos:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
nota: el uso de la lista */ .*/
funciona en bash, pero también muestra las carpetas .
y ..
mientras está en zsh no las mostrará, pero arrojará un error si no hay ningún archivo oculto en la carpeta
Una versión más limpia que incluirá directorios ocultos y excluirá ../ estará con la opción dotglob:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
(o setopt dotglob
en zsh)
puedes desarmar dotglob con
shopt -u dotglob
Esto incluirá la ruta completa en cada directorio de la lista:
for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
Use find
con -exec
para recorrer los directorios y llamar a una función en la opción exec:
dosomething () {
echo "doing something with $1"
}
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' {} \;
Use shopt -s dotglob
o shopt -u dotglob
para incluir / excluir directorios ocultos
ls -l | grep ^d
o:
ll | grep ^d
Puedes configurarlo como un alias
ls
respuesta basada en la lista , que enumera los directorios.
ls
: mywiki.wooledge.org/ParsingLs