Respostas:
Você pode especificar uma barra no final para corresponder apenas aos diretórios:
for d in */ ; do
echo "$d"
done
[[ -L $d ]]se $ d é um link simbólico.
set -Pafeta apenas comandos que alteram o diretório. sprunge.us/TNac
[[ -L "$f" ]]não excluir links simbólicos neste caso com */, você tem que tirar a barra final com [[ -L "${f%/}" ]](veja Testar link com barra invertida )
Você pode testar com -d:
for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
Este é um dos operadores de teste de arquivo .
if [[ -d "$f" && ! -L "$f" ]]excluirá links simbólicos
if [[ "$f" = "*" ]]; then continue; fi
Cuidado que a solução do choroba, embora elegante, pode provocar um comportamento inesperado se nenhum diretório estiver disponível no diretório atual. Nesse estado, em vez de pular o forloop, o bash executará o loop exatamente uma vez onde dfor igual a */:
#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo $d
done
Eu recomendo usar o seguinte para proteger 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
Esse código percorrerá todos os arquivos no diretório atual, verificará se fé um diretório e ecoará fse a condição retornar verdadeira. Se ffor igual a */, echo $fnão será executado.
shopt -s nullglob.
Se você precisar selecionar arquivos mais específicos do que apenas os diretórios usam finde passá-los para while read:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Use shopt -u dotglobpara excluir diretórios ocultos (ou setopt dotglob/ unsetopt dotglobno zsh).
IFS=para evitar a divisão de nomes de arquivos que contenham um dos $IFS, por exemplo:'a b'
veja a resposta do AsymLabs abaixo para mais findopções
edit:
Caso você precise criar um valor de saída a partir do loop while, é possível contornar o subshell extra com este truque:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
Você pode usar o bash puro para isso, mas é melhor usar o find:
find . -maxdepth 1 -type d -exec echo {} \;
(encontrar adicionalmente incluirá diretórios ocultos)
shopt -s dotglobpara bashincluir diretórios ocultos. O seu também incluirá .. Observe também que -maxdepthnão é uma opção padrão ( -pruneé).
dotglobopção é interessante, mas dotglobsó se aplica ao uso de *. find .incluirá sempre diretórios ocultos (eo dir atual, bem)
Isso é feito para localizar os diretórios visíveis e ocultos no atual diretório de trabalho, excluindo o diretório raiz:
apenas percorrer os diretórios:
find -path './*' -prune -type d
para incluir links simbólicos no resultado:
find -L -path './*' -prune -type d
para fazer algo em cada diretório (excluindo links simbólicos):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
excluir diretórios ocultos:
find -path './[^.]*' -prune -type d
para executar vários comandos nos valores retornados (um exemplo muito artificial):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '{}' sh -c \
"printf 'first: %-40s' '{}'; printf 'second: %s\n' '{}'"
em vez de 'sh -c' também pode usar 'bash -c', etc.
... -print0 | xargs -0 ...se você não souber quais são os nomes exatos.
find * | while read file; do ...
Você pode percorrer todos os diretórios, incluindo os diretórios ocultos (começando com um ponto) em uma linha e vários comandos com:
for file in */ .*/ ; do echo "$file is a directory"; done
Se você deseja excluir links simbólicos:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
note: o uso da lista */ .*/funciona no bash, mas também exibe as pastas .e, ..enquanto estiver no zsh, não as mostrará, mas gerará um erro se não houver um arquivo oculto na pasta
Uma versão mais limpa que incluirá diretórios ocultos e excluirá ../ estará com a opção dotglob:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
(ou setopt dotglobem zsh)
você pode desabilitar o dotglob com
shopt -u dotglob
Isso incluirá o caminho completo em cada diretório da lista:
for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
Use findwith -execpara percorrer os diretórios e chamar uma função na opção exec:
dosomething () {
echo "doing something with $1"
}
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' {} \;
Use shopt -s dotglobou shopt -u dotglobpara incluir / excluir diretórios ocultos
ls -d */ | while read d
do
echo $d
done
This is one directory with spaces in the name- mas é analisado como múltiplo.
ls -l | grep ^d
ou:
ll | grep ^d
Você pode configurá-lo como um alias
lsda resposta com base nessa lista , que lista os diretórios.
ls: mywiki.wooledge.org/ParsingLs