Ubuntu – Correct file extensions

file formatfiles

I have about 12000 images of different file types but every one of them was renamed *.jpg.

Now I want to give them their proper extensions back, how can I do it

Best Answer

You can do it relatively easily in bash:

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

This is the same idea as @A.B's answer but using shell globs instead of find. The ${f%%.*} is the filename without its extension. The -0 of the file command makes it print a \0 after the file name which we then use to grep the file type. This should work with arbitrary file names, including those that contain spaces, newlines or anything else. The ${type,,} is a trick to get lower case extensions. It would convert PNG to png.

You didn't say in your question, but if you need this to be recursive and descend into subdirectories, you could use this instead:

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

The shopt -s globstar will enable bash's globstar option which lets ** match subdirectories:

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.