Renomear lote - vários tipos de imagem

2

Eu tenho um grande número de imagens que copiei de um disco rígido externo com falha. Todas as imagens estão bem e não têm corrupção, mas estranhamente um grande número delas está faltando extensões. Os arquivos são uma mistura de jpg, png e gif, e são nomeados na estrutura a seguir, tudo em uma única pasta.

1
2
3
4.jpg
5.png

etc

Alguns arquivos têm extensões, enquanto muitos não são e são apenas números. Existem cerca de 4000 imagens nesta pasta, pelo que a renomeação manual não é uma opção.

Existe algum script ou programa que possa ser usado para determinar a extensão através de meta-dados e adicioná-lo aos arquivos, conforme necessário?

Eu usei "pyrenamer" do centro de software por anos para renomear arquivos, mas parece que não é possível adicionar extensões.

Qualquer ajuda seria muito apreciada, minha codificação é uma droga e eu não consigo descobrir sozinha.

    
por KhaosDvorak 20.10.2014 / 12:07

3 respostas

4

Abaixo de uma solução python (script).

O script usa o módulo imghdr para reconhecer o tipo de arquivo. Ele adicionará as extensões de arquivo corretas (se ausentes) dos seguintes tipos:

rgb, gif, pbm, pgm, ppm, tiff, rast, xbm, jpeg, bmp, png 

Se o arquivo já tiver uma extensão de arquivo, ele será ignorado. Caso o arquivo seja de um tipo de arquivo desconhecido (se estiver danificado, por exemplo), o arquivo é reportado como "não foi possível determinar":

could not determine: /home/jacob/Bureaublad/picturetest/blub

O script:

#!/usr/bin/env python3

import os
import imghdr
import shutil

directory = "/path/to/pictures"

for name in os.listdir(directory):
    # combining file+its directory:
    file = directory+"/"+name
    # only files without a dot are subject to renaming (else the file already has a file extension or is a hidden file):
    if name.count(".") == 0:
        # fetch the file extension from the file:
        ftype = imghdr.what(file)
        # if it is impossible to get the extension (if the file is damaged for example), the file(s) will be listed in the terminal window:
        if ftype != None:
            shutil.move(file, file+"."+ftype)
        else:
            print("could not determine: "+file)

Cole-o em um arquivo vazio, salve-o como rename.py, configure o diretório para as imagens na directory = "/path/to/pictures" -line e execute-o pelo comando:

python3 /path/to/rename.py

Renomeie recursivamente

Caso suas imagens não estejam em um diretório "flat", mas em um diretório em camadas, use a versão abaixo. Ele irá verificar (e reparar se necessário) extensões de arquivo dentro da pasta atual do arquivo.

#!/usr/bin/env python3

import os
import imghdr
import shutil

directory = "/path/to/pictures"

for root, dirs, files in os.walk(directory):
    for name in files:
        file = root+"/"+name
        if name.count(".") == 0:
            ftype = imghdr.what(file)
            if ftype != None:
                shutil.move(file, file+"."+ftype)
            else:
                print("could not determine: "+file)
    
por Jacob Vlijm 20.10.2014 / 13:25
2

Um one-liner usando o comando rename :

rename 's/.*/use File::MimeInfo::Magic qw#mimetype extensions#; sprintf("%s.%s", $&, extensions(mimetype($&)))/e' * -vn

ele está usando o módulo Perl File::MimeInfo para consultar o arquivo (como o comando file faz) para descobrir qual é o arquivo e, em seguida, anexar a primeira extensão que o MimeInfo tem para esse tipo MIME no arquivo .

Em alguns casos, isso pode resultar em extensões usadas com menos frequência (como jpeg ou jpe para o que a maioria das pessoas chamaria de arquivos jpg), mas você pode fazer um segundo passo para corrigi-las facilmente:

rename 's/\.jpe$/.jpg/' *

Mas a maioria dos aplicativos não se importará se você especificar arquivos .jpe para que isso não seja necessário na maioria das vezes.

Os comandos rename acima estão definidos no modo de teste.
Eles não farão nada até que você remova o argumento -n do final.

    
por Oli 20.10.2014 / 13:22
1

Script simples

#!/bin/bash

for file in ~/path/to/images/*; do
    TYPE=$(file --mime-type -b "$file" | cut -f2 -d/);
    if [[ ! $file =~ \.$TYPE ]]; then
        echo mv -v "$file" "$file.$TYPE";
    fi
done

Explicação de TYPE=$(file --mime-type -b "$file" | cut -f2 -d/); (encontrar tipo de arquivo)

encontre a extensão de cada comando $file usando file (determine o tipo de arquivo).

--mime-type, --mime-encoding opção usada para imprimir apenas o (s) elemento (s) especificado (s).

-b, --brief opção usada para não prefixar nomes de arquivos em linhas de saída (modo breve).
Veja também arquivo man para mais informações.

Agora extraímos o tipo de arquivo e o salvamos em TYPE variable.

E o que é o comando cut -f2 -d/ ? Usado para imprimir apenas o tipo de extensão, como png em image/png output de file --mime-type -b "$file" result.

-f2 imprime a segunda parte com / delimitador ( -d opção) entre os campos. ex: imprima png em image/png . Veja também man cut para mais informações.

Explicação de if [[...]]; (verificação da extensão do arquivo)

Pulamos todas as extensões existentes com uma regex simples, usando o operador =~ dentro de um teste [[...]] em condição if:

if [[ $file =~ \.$TYPE ]];

Enquanto $file são os nomes dos seus arquivos de imagens e $TYPE é sua extensão, nós encontramos e armazenamos isso na variável TYPE em TYPE=$(file --mime-type -b "$file" | cut -f2 -d/); .

Então, pulamos para renomear todos os arquivos que possuam uma extensão.

! se refere a: se o arquivo não possui uma extensão consigo, então renomeie e adicione sua extensão no final do nome.

Explicação de echo mv -v "$file" "$file.$TYPE"; (renomear etapa)

Nesta linha, na verdade, estamos anexando a extensão de arquivo (se $file não possuir uma extensão com ela) no final do arquivo $file usando o comando mv . mv também está usando para renomear arquivos / diretório.

Em seguida, renomeamos $file para $file.$TYPE . Por exemplo, o arquivo 1 será renomeado para 1.png se o tipo de arquivo for png format.

in theory actually above mv command do this: rename filename -> filename.filetype

Esse nome de arquivo armazenado em $file variable e filetype armazenados em $TYPE variable.

Como você pode usar esse script?

Copie e cole o script em gedit e salve-o com seu nome favorito ex: batchRename , em seguida Abra o Terminal e execute-o com o seguinte comando:

bash batchRename

NÃO esqueça, antes de executar o script, verifique seu caminho de imagens corretas /path/to/images/ e renomeie seus arquivos depois de verificar o resultado com o comando echo , remova echo do início echo mv -v "$file" "$file.$TYPE" e execute o script novamente gosta de renomear;)

    
por αғsнιη 20.10.2014 / 12:47