J'ai environ 12 000 images de types de fichiers différents, mais chacune d'entre elles a été renommée * .jpg.
Maintenant, je veux leur rendre leurs extensions appropriées, comment puis-je le faire
Vous pouvez le faire relativement facilement en bash:
for f in *jpg; do
type=$(file -0 -F" " "$f" | grep -aPo '\0\s*\K\S+')
mv "$f" "${f%%.*}.${type,,}"
done
C'est la même idée que la réponse de @A.B, mais en utilisant des globes de shell au lieu de find
. Le ${f%%.*}
est le nom du fichier sans son extension. Le -0
de la commande file
lui permet d'imprimer un \0
après le nom du fichier que nous utilisons ensuite pour grep
son type. Cela devrait fonctionner avec des noms de fichiers arbitraires, y compris ceux qui contiennent des espaces, des nouvelles lignes ou toute autre chose. Le ${type,,}
est une astuce pour obtenir des extensions minuscules. Cela convertirait PNG
en png
.
Vous n'avez pas dit dans votre question, mais si vous avez besoin que cela soit récursif et que vous descendiez dans des sous-répertoires, vous pouvez utiliser ceci à la place:
shopt -s globstar
for f in **/*jpg; do
type=$(file -0 -F" " "$f" | grep -aPo '\0\s*\K\S+')
mv "$f" "${f%%.*}.${type,,}"
done
Le shopt -s globstar
activera l'option globstar de bash qui permet à **
de faire correspondre les sous-répertoires:
globstar
Si défini, le modèle ** utilisé dans un contexte d'expansion de nom de chemin correspond à tous les fichiers et à aucun ou plusieurs répertoires et sous-répertoires. Si le modèle est suivi d'un /, seuls les répertoires et les sous-répertoires correspondent.
Le script ci-dessous peut être utilisé pour renommer (de manière récursive) une extension mal définie, .jpg
, en la correcte. S'il trouve un fichier illisible, il le signalera dans la sortie du script.
Le script utilise le module imghdr
pour reconnaître les types suivants: rgb
, gif
, pbm
, pgm
, ppm
, tiff
, rast
, xbm
, jpeg
, bmp
, png
. Plus d'informations sur le module imghdr
ici . La liste peut être étendue avec plusieurs types, comme mentionné dans le lien.
En l’occurrence, il renomme spécifiquement les fichiers portant l’extension .jpg
, comme indiqué dans la question. Avec une modification mineure, il peut être approprié de renommer n'importe quelle extension, ou un ensemble d'extensions spécifique, en une extension correcte (ou sans extension, comme ici ).
#!/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)
rename.py
Exécutez-le à l'aide de la commande:
python3 /path/to/rename.py <directory>
Remarque: mon approche semble trop complexe. Je préférerais que les terdons répondent à votre place.
Vous pouvez utiliser la commande file
pour déterminer le type de fichier:
% 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
Avec cette information, les fichiers peuvent être renommés:
Veuillez faire un test avant d'appliquer la commande à vos images
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)
}'
Exemple
% 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