Listando todos os arquivos no diretório

1

Eu tenho um script bash onde eu preciso fazer um loop em todos os arquivos em uma pasta.

Esta é a minha função atual para tothat:

function listDir(){

   for file in "$1"/*;
   do 
      echo $file
   done 
}

O problema é que ele não está listando arquivos ou pastas ocultos (.hiddenFile). Como posso conseguir isso?

De acordo com a resposta de Kusalananda, editei meu script para se parecer com:

listDir () {
    for file in $(find "$1" -maxdepth 1 -mindepth 1 -print);
    do
       echo $file
    done
}

No entanto, isso não está funcionando com pastas com espaços no nome. Note que eu preciso do loop for para fazer outras coisas com os nomes dos arquivos, e não apenas listá-los.

Como posso resolver isso?

    
por SwDev 05.10.2018 / 14:09

2 respostas

2

Por padrão, o padrão de globbing da concha * não corresponde a nomes ocultos.

Em bash , você pode fazer isso ativando a opção dotglob shell. Você faz isso com shopt -s dotglob .

Note que você também teria que citar a expansão de $file em seu código, ou o shell executaria a divisão de palavras e a globalização de nomes de arquivo em seu valor.

listDir () (
    shopt -s dotglob
    for pathname in "$1"/*; do
        printf '%s\n' "$pathname"
    done
)

Se você precisar fazer outras coisas com $pathname no loop acima, certifique-se de aspas duplas da expansão da variável como "$pathname" . Isso faria com que a função funcionasse para nomes de arquivos que contenham todos os tipos de caracteres.

Ao chamar a função, certifique-se de citar o nome do diretório se ele contiver espaços:

listDir "my directory/here somewhere"

Duas abordagens alternativas (supondo que você só precisa listar os arquivos):

listDir () (
    shopt -s dotglob
    printf '%s\n' "${1:-.}"/*
)

Ao incluir o corpo da função em ( ... ) (um subshell), garantimos que a opção dotglob shell não esteja definida no shell de chamada.

Usando ${1:-.} no lugar de apenas $1 , usamos . (o diretório atual) como o diretório padrão a ser listado, se nenhum diretório (ou uma string vazia) for fornecido.

O utilitário printf reutilizará sua string de formato se receber mais argumentos do que os espaços reservados na string de formatação. Aqui, usamos esse fato para imprimir os nomes de arquivos como uma lista delimitada por nova linha.

Usando find , que não precisa de dotglob :

listDir () {
    find "${1:-.}" -maxdepth 1 -mindepth 1 -print
}

Se você quiser fazer outra coisa com os arquivos encontrados quando estiver usando find , então não tente fazer um loop pela saída de find . Em vez disso, use -exec :

listDir () {
    find "${1:-.}" -maxdepth 1 -mindepth 1 -exec sh -c '
        for pathname do
            # code that does something with "$pathname"
        done' sh {} +
}

Relacionados:

por 05.10.2018 / 14:15
0

Como você marcou o bash, também pode usar matrizes:

shopt -s dotglob
files=( "$1"/* )

Depois, você pode imprimi-los ou operá-los:

printf "File: %s\n" "${files[@]}"

ou

rm "${files[@]}"

ou

for f in "${files[@]}"; do mv "${f}" "renamed-${f}"; done
    
por 05.10.2018 / 18:34

Tags