2015-06-06 21 views
5

Quindi ho una cartella con migliaia di file di immagine, tutti salvati come .jpg.Rinominare un gruppo di immagini PNG con estensione ".jpg" su ".png"

Il problema è che alcuni di questi file sono in realtà file immagine PNG, quindi non si aprono in molti programmi, a meno che non modifichi manualmente la loro estensione su .png. Ad esempio, il visualizzatore di immagini di Ubuntu getta questo errore:

"Error interpreting JPEG image file (Not a JPEG file: starts with 0x89 0x50)"

ho già gestiva un hexdump di alcuni di questi file per confermare questo errore e si estrae.

Sto cercando un modo semplice per trovare tutti i file con l'estensione errata tra gli altri file e modificare la loro estensione. Come farei questo con uno script bash per esempio? Finora non ne ho idea. Tutto l'aiuto è apprezzato!

risposta

6
for f in *.jpg ; do 
    if [[ $(file -b --mime-type "$f") = image/png ]] ; then 
    mv "$f" "${f/%.jpg/.png}" 
    fi 
done 

Questo ottiene una lista di .jpg file, allora per ogni chiama l'utilità file su di esso per ottenere il tipo MIME. Se questo è image/png, quindi rinomina il file utilizzando una sostituzione string manipulation.

0

Non sono sicuro dei comandi appropriati per uno script bash ma è possibile scrivere facilmente un file C++ per provare ad aprire questi file e rilevare l'errore. I file in cui viene rilevato l'errore non saranno di tipo appropriato (presupponendo che questo sia l'unico problema). Se sai che i tipi di file errati dovrebbero essere PNG, puoi rinominare il file. Qualcosa di simile lo pseudocodice:

For (ALL_FILES) 
{ 
    try 
    { 
    open(FILENAME); 
    } 
    catch 
    { 
    rename(FILENAME, NEW_FILENAME); 
    } 
} 
+1

Ciò presuppone che i tentativi 'open' di * analizzare * i dati del file * e * che si basa sull'estensione del file siano corretti. Un semplice 'generico' 'open' avrà sempre successo su un file esistente. Un 'smart' 'open' ignorerà l'estensione del file e userà la [firma magica] del file (http://en.wikipedia.org/wiki/List_of_file_signatures) per determinare il suo tipo e potrebbe quindi avere successo. – usr2564301

1

Si desidera utilizzare file e analizzare l'output. Si può verificare se si tratta di un JPEG o PNG controllando la parte iniziale della produzione:

F="filename.jpg" 
TYPE=$(file -b $F) 
[[ $TYPE == JPEG\ image\ data* ]] && echo "jpg" 
[[ $TYPE == PNG\ image\ data* ]] && echo "png" 

È possibile modificare l'estensione mettendo a nudo la .jpg con basename. Ad esempio, il seguente sarà cambiare l'estensione del file con l'estensione $F.jpg a .png:

mv $F $(dirname $F)/$(basename $F .jpg).png 
1

In primo luogo ottenere un elenco di file e li rendono in un file. Quindi elaborare l'elenco su un loop in modo che sia possibile modificare automaticamente i file uno ad uno.

#!/bin/bash 

FILE=/tmp/list ## Assuming the list of files are in this file. 
for file in $(cat $FILE); do 
    OLD_FILE=$file 
    NEW_FILE=$(echo $file|sed -e 's/jpg$/png/') 
    mv $OLD_FILE $NEW_FILE 
done 
1

Utilizzare file (1) per determinare il tipo di tutti i file. Utilizzare grep (1) per filtrare questo elenco, rimuovendo tutti i file JPEG appropriati. Ciò che rimane è un elenco di file che non possono essere riconosciuti come JPEG.

In una sola riga

file *.jpg | grep -v "JPEG image data" 

- fare in modo di verificare che JPEG image data è proprio ciò che file ritorni su un file JPG identificato correttamente.

È possibile utilizzare sed (1) per rimuovere il materiale dopo i due punti : e finire con il nome di file:

file *.jpg | grep -v "JPEG image data" | sed 's/:.*//' 

.. che è la fine del mio bash-fu.A questo punto memorizzerei l'elenco risultante in un file (aggiungi > list) e utilizzerei GREP in un editor di testo per riscrivere tutte le righe con un comando di rinomina appropriato, quindi eseguirlo.