Para loop no Unix: incluindo arquivos de subdiretórios [duplicados]

6

Um loop for simples no Unix seria:

for FILE in $BASE_WORK_DIR/*.pdf
   do
     echo $FILE
   done

Isso ecoará todos os arquivos .pdf dentro do diretório BASE_WORK_DIR.

E se BASE_WORK_DIR também contiver subdiretórios que também contenham o arquivo pdf.

Nesse caso, como projetar meu loop para obter todos os arquivos pdf de BASE_WORK_DIR , bem como os subdiretórios de BASE_WORK_DIR ?

    
por Vicky 22.01.2014 / 13:25

3 respostas

6

A sintaxe padrão e canônica e confiável é:

find . -type f -name '*.pdf' -exec sh -c '
  for f do
    something with "$f"
  done' sh {} +

(note que ele pode executar vários sh invocação se a lista de arquivos é muito grande).

Com zsh , o equivalente seria

for f (./**/*(.NDoN)) {
  something with "$f"
}

( . para -type f , D para incluir arquivos ocultos, oN para não incomodar a classificação da lista, N para não reclamar se não houver nenhum arquivo correspondente), exceto que você não obteria mensagens de erro para os diretórios aos quais você não tem acesso.

    
por 22.01.2014 / 16:42
6

Em bash4 , e seguindo os links simbólicos para diretórios é desejável, você pode habilitar globstar e usar ** :

shopt -s globstar
for file in "$base_work_dir"/**/*.pdf
do
  echo "$file"
done

Caso contrário, em um script sh , find provavelmente é a melhor maneira:

IFS='
'
set -f
for file in $(find "$base_work_dir" -name *.pdf)
do
  echo "$file"
done

(adicione a opção -L a find para seguir links simbólicos como bash globstar)

Note que você terá problemas aqui se algum nome de arquivo contiver novas linhas.

    
por 22.01.2014 / 13:40
3

Outra solução com find que resolveria o problema de novas linhas em nomes de arquivos:

find "$BASE_WORK_DIR" -name '*.pdf' -print0 |
  while IFS= read -d '' -r file;do
    # your magic here
  done

< em> Caveat emptor : isso só funciona em Zsh e Bash.

-print0 só funciona em algumas implementações find como o GNU find . Use -exec printf '%s%code%' {} + se sua descoberta não der suporte a isso.

    
por 22.01.2014 / 14:03

Tags