Você está tentando muito difícil obter os diretórios no diretório atual. Tudo o que você precisa fazer é:
for dir in */; do echo "dir: $dir"; done
# .........^^
Se você quiser armazená-los em uma matriz:
dirs=( */ )
Ambas as linhas a seguir retornam a lista de diretórios de um dos meus diretórios.
O primeiro deles usa um padrão de nome, enquanto eu preciso escolher dirs, pois eles realmente são diretórios para processá-los em um loop. Eu gostaria, portanto, de usar o segundo:
ls -l | awk '{print $9}' | grep 'dirsPrefix*'
find . -maxdepth 1 -type d | grep -v \.$ | awk -F'./' '{print $2}'
Mas dentro de um ksh para loop, o primeiro está funcionando ao contrário do segundo ... Por quê ? :
(solução alternativa:
for dir in 'find . -maxdepth 1 -type d -exec echo "{}" \; | awk -F'/' {print $2}'
do
echo "dir: $dir"
done
funcionará)
Isso também funciona:
for dir in 'ls -l | awk '{print $9}' | grep 'dirsPrefix*''
do
echo "dir: $dir"
done
Mas isso não acontece:
for dir in 'find . -maxdepth 1 -type d | grep -v \.$ | awk -F'./' '{print $2}''
do
echo "dir: $dir"
done
Você está tentando muito difícil obter os diretórios no diretório atual. Tudo o que você precisa fazer é:
for dir in */; do echo "dir: $dir"; done
# .........^^
Se você quiser armazená-los em uma matriz:
dirs=( */ )
Altere para isto:
for dir in $(find . -maxdepth 1 -type d | grep -v \.$ | awk -F'./' '{print $2}')
do
echo "dir: $dir"
done
Não sei explicar por que funciona, mas sei que você deve usar $()
sobre backticks.
Você precisa perceber que o comando que está executando, por exemplo,
for dir in 'find . -maxdepth 1 -type d | grep -v \.$ | awk -F'./' '{print $2}''
existem 2 níveis de interpretação de citações. No primeiro nível, isto é, no nível da linha de comando, onde o comando é emitido, o texto sob os backquotes '....' é primeiro varrido para barras invertidas e $ variáveis, assim como em uma interpolação de aspas duplas. Já que $
está solitário no final, então não será expandido. Não há mal em escapar disso.
Então, isso deve deixar esse grep -v \.$ ----> grep -v \.$
Agora, após o término deste passo, ele será entregue a um subshell para execução. E nessa sub-linha, o comando grep -v \.$
é analisado e a barra invertida é removida, então o que grep
executável obtém no final desta fase é: grep -v .$
Agora, todas as linhas não-vazias corresponderão a esse padrão e encontrarão todas as linhas não-vazias geradas, pela simples razão de que os nomes dos arquivos não devem ser não-vazios.
Então, isso significa que todos os outputs de find
serão selecionados e, portanto, o inverso disso implica que nenhuma saída de find deve ser selecionada. Então o awk está todo vestido, mas não tem para onde ir.
Há muitas coisas que você pode fazer para corrigir o problema.
grep -v \\.$
Com base no que acontece em cada etapa da expansão de cotação para este cenário, convença-se de que essa correção funciona. grep -v '\.$'
grep -v '[.]$'
find
: find . -maxdepth 1 -type d ! -name . -exec sh -c '
for d do printf "dir: %s\n" "${d:2}"; done
' sh {} +
Existe um problema com a expressão grep
. Ele corresponderá a todos os nomes de diretório que terminem com .
, mas também parece distorcer a saída de alguma forma para tornar for
confuso. Há muitas coisas que você pode fazer sobre isso.
Alterar a expressão do grep para grep -v "^\.$"
provavelmente será mais correto (pois corresponderá apenas ao diretório .
) e funcionará no seu for
-loop
Como já foi apontado por @Jesse_b, é melhor, por vários motivos, usar a expressão $(..)
para execução. Isso resolverá seu problema imediato, mas não corrigirá o possível bug.
Você pode usar find
até o final, tornando este script um pouco mais simples:
for dir in 'find . -maxdepth 1 -type d ! -name "." -printf "%f "'
do
echo $dir
done
Não é provável que todas essas soluções sejam problemáticas se houver diretórios com espaços ( ) em seus nomes.
Tags find ksh shell command-substitution for