Corrigir as extensões de arquivo

14

Eu tenho cerca de 12 mil imagens de diferentes tipos de arquivos, mas cada um deles foi renomeado * .jpg.

Agora eu quero dar a eles as devidas extensões, como posso fazer isso

    
por akabhirav 03.06.2015 / 20:31

3 respostas

21

Você pode fazer isso com relativa facilidade no bash:

for f in *jpg; do 
    type=$(file -0 -F" " "$f" | grep -aPo '
shopt -s globstar
for f in **/*jpg; do 
    type=$(file -0 -F" " "$f" | grep -aPo '
for f in *jpg; do 
    type=$(file -0 -F" " "$f" | grep -aPo '
shopt -s globstar
for f in **/*jpg; do 
    type=$(file -0 -F" " "$f" | grep -aPo '%pre%\s*\K\S+') 
    mv "$f" "${f%%.*}.${type,,}"  
done
\s*\K\S+') mv "$f" "${f%%.*}.${type,,}" done
\s*\K\S+') mv "$f" "${f%%.*}.${type,,}" done
\s*\K\S+') mv "$f" "${f%%.*}.${type,,}" done

Esta é a mesma idéia que a resposta do @ A.B, mas usando shell globs ao invés de find . O ${f%%.*} é o nome do arquivo sem sua extensão. O comando -0 do comando file faz com que ele imprima grep após o nome do arquivo que usamos em ${type,,} do tipo de arquivo. Isso deve funcionar com nomes de arquivos arbitrários, incluindo aqueles que contêm espaços, novas linhas ou qualquer outra coisa. O PNG é um truque para obter extensões de letras minúsculas. Ele converteria png para shopt -s globstar .

Você não disse em sua pergunta, mas se precisar que isso seja recursivo e desça em subdiretórios, você pode usar isso:

%pre%

O ** ativará a opção globstar do bash, que permite que %code% corresponda a subdiretórios:

globstar

If set, the pattern ** used in a pathname expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a /, only directories and subdirectories match.

    
por terdon 03.06.2015 / 22:39
10

O script abaixo pode ser usado para (recursivamente) renomear uma extensão definida incorretamente, .jpg , para a correta. Caso encontre um arquivo ilegível, ele o informará na saída do script.

O script usa o módulo imghdr para reconhecer os seguintes tipos: rgb , gif , pbm , pgm , ppm , tiff , rast , xbm , jpeg , bmp , png . Mais informações sobre o módulo imghdr aqui . A lista pode ser estendida com mais tipos, conforme mencionado no link.

Como está, especificamente renomeia arquivos com a extensão .jpg , como mencionado na pergunta. Com uma pequena alteração, pode ser adequado renomear qualquer extensão, ou um conjunto específico de extensões, para a correta (ou sem extensão, como aqui ).

O script:

#!/usr/bin/env python3
import os
import imghdr
import shutil
import sys

directory = sys.argv[1]

for root, dirs, files in os.walk(directory):
    for name in files:
        file = root+"/"+name
        # find files with the (incorrect) extension to rename
        if name.endswith(".jpg"):
            # find the correct extension
            ftype = imghdr.what(file)
            # rename the file
            if ftype != None:
                shutil.move(file, file.replace("jpg",ftype))
            # in case it can't be determined, mention it in the output
            else:
                print("could not determine: "+file)

Como usar

  1. Copie o script em um arquivo vazio, salve-o como rename.py
  2. Execute-o pelo comando:

    python3 /path/to/rename.py <directory>
    
por Jacob Vlijm 03.06.2015 / 21:34
2

Nota: Minha abordagem parece ser muito complexa. Eu preferiria que os terdons respondessem em seu lugar.

Você pode usar o comando file para determinar o tipo de arquivo:

% file 20050101_14-24-37_330.jpg 
20050101_14-24-37_330.jpg: JPEG image data, EXIF standard 2.2, baseline, precision 8, 1200x1600, frames 3

% file test.jpg
test.jpg: PNG image data, 1192 x 774, 8-bit/color RGBA, non-interlaced

Com esta informação, os arquivos podem ser renomeados:

Por favor, faça um teste antes de aplicar o comando às suas imagens

find . -type f -iname "*.jpg" -print0 | xargs -0 -I{} file -F"<separator>" {} | 
 awk -F " image data" '{print $1}' | 
  awk -F"<separator> " '{
   system("mv \""$1"\" $(dirname \""$1"\")/$(basename -s .jpg \"" $1 "\")."$2)
   }'

Exemplo

% find . -type f -name "*.jpg"
./test.jpg
./sub/20050101_14-24-37_330.jpg

% find . -type f -iname "*.jpg" -print0 | xargs -0 -I{} file -F"<separator>" {} | awk -F " image data" '{print $1}' | awk -F"<separator> " '{system ("mv \""$1"\" $(dirname \""$1"\")/$(basename -s .jpg \"" $1 "\")."$2)}'

% find . -type f -iname "*"    
./test.PNG
./sub/20050101_14-24-37_330.JPEG
    
por A.B. 03.06.2015 / 21:06