Use “find” em vez de “for-do-done” para procurar subdiretórios também

1

No OS X 10.8 eu tenho um par de pastas com imagens, mas nem todos os arquivos têm a extensão correta, existem GIFs que são nomeados JPG, etc.

Eu tenho um one-liner que faz o trabalho para o diretório real:

for f in * ; do type=$(file "$f" | tr "[A-Z]" "[a-z]" | awk '{print $2}') ; mv "$f" "${f%.*}.$type" ; done

Agora, gostaria de usar "find" para pesquisar também as subpastas, mas sempre falho.

Alguma dica?

    
por X-File 24.11.2016 / 20:31

4 respostas

0

Nesse caso, você pode encontrar facilmente arquivos que NÃO correspondem à extensão .jpg:

find . -type f -not "*.jpg"

Você também pode percorrer os resultados e verificar se os arquivos são realmente jpg:

find . -type f -not "*.jpg" | while read fname; do
  if [[ $(file $fname) == *"JPG"*]]
    then echo $fname
  fi
done
    
por 24.11.2016 / 21:16
0

O mais fácil seria ativar a globalização recursiva de arquivos, por exemplo, no Bash:

shopt -s globstar
for f in **/*.*; do
    type=$(file "$f" | tr "[A-Z]" "[a-z]" | awk '{print $2}')
    mv -- "$f" "${f%.*}.$type"
done

Dessa forma, você evita ter que analisar find output. O problema é que, se houver muitos arquivos, esse comando poderá falhar, pois poderá exceder o tamanho máximo de uma linha de comando. Isso ocorre porque os nomes dos arquivos em **/*.* serão expandidos pelo Bash antes que o comando seja executado.

Portanto, a alternativa é usar find , direcionando sua saída para while e read .

find . -type f -print0 | while IFS= read -r -d '' f
    type=$(file "$f" | tr "[A-Z]" "[a-z]" | awk '{print $2}')
    mv -- "$f" "${f%.*}.$type"
done

Para algumas práticas recomendadas que funcionam com listas de arquivos, consulte: link

    
por 25.11.2016 / 11:23
0

Eu encontrei este caminho para o meu prob, mas não é realmente elegante :-P

find . -type f -name "*.*" -exec sh -c 'name=$(basename {} | cut -d. -f1) ; type=$(file {} | tr "[A-Z]" "[a-z]" | cut -d" " -f2) ; mv 'basename {}' "$name.$type"' \;
    
por 28.11.2016 / 16:35
0

A partir dos comentários anteriores, acho que você está procurando uma maneira de analisar os resultados sem fazer um loop sobre eles, usando apenas o find:

find . -type f -not "*.jpg" -exec sh -c "if [[ $(file {}) == *'JPG'* ]] then; echo {}; fi" \;

    
por 28.11.2016 / 16:41