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 -Psolo 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 forciclo, bash ejecutará el ciclo exactamente una vez donde des 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 fes un directorio, luego hará eco fsi la condición devuelve verdadero. Si fes igual a */, echo $fno se ejecutará.
shopt -s nullglob.
Si necesita seleccionar archivos más específicos que solo los directorios usan findy pasarlos a while read:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Se usa shopt -u dotglobpara excluir directorios ocultos (o setopt dotglob/ unsetopt dotgloben 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 findopciones
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 dotglobpara bashincluir directorios ocultos. El tuyo también incluirá .. También tenga en cuenta que -maxdepthno es una opción estándar ( -prunees).
dotglobopción es interesante pero dotglobsolo 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 dotgloben 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 findcon -execpara 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 dotglobo shopt -u dotglobpara incluir / excluir directorios ocultos
ls -l | grep ^d
o:
ll | grep ^d
Puedes configurarlo como un alias
lsrespuesta basada en la lista , que enumera los directorios.
ls: mywiki.wooledge.org/ParsingLs