I have a bunch of image files from misnamed scans/faxes I need to fix for our Linux users. It turns out we have a bunch of scans that are PNG files that are labled as *.jpg visa versa. Under Windows this was never an issue as Explorer/Office would just ignore the extension. But under Linux, Eye of GNOME etc end up just refusing to open the file because the contents don't match the extension.

Does anyone have any recommendations for a tool or a little piece of script that could do this? I could write a C program to do this, but that seems a bit overkill. Just sitting down and manually renaming manually isn't an option, there are thousands.

Edit: I see the file command will look at the actual contents of the file and display what it is. I'm not quite sure how to use the information from it though.


You'll want to iterate over the files that look like image files, call file to see what they really are, then rename them appropriately

for f in *.{jpg,JPG,png,PNG,jpeg,JPEG}; do 
    type=$( file "$f" | grep -oP '\w+(?= image data)' )
    case $type in  
        PNG)  newext=png ;; 
        JPEG) newext=jpg ;; 
        *)    echo "??? what is this: $f"; continue ;; 
    ext=${f##*.}   # remove everything up to and including the last dot
    if [[ $ext != $newext ]]; then
        # remove "echo" if you're satisfied it's working
        echo mv "$f" "${f%.*}.$newext"
  • 1
    That looks pretty close to the script I started working on. But when I try run that script I get ??? what is this: *.{jpg,JPG,png,PNG,jpeg,JPEG} – BlamKiwi Sep 16 '14 at 13:24
  • 1
    @MorphingDragon What shell or version of Bash are you using? Did you disable brace expansion? Or is there no such file in your directory? Run shopt -s nullglob before, maybe, so that the glob doesn't expand in that case. – slhck Sep 16 '14 at 13:27
  • 4.3.11 (Mint 17) – BlamKiwi Sep 16 '14 at 13:28
  • Instead of the braces you can use find commands, so the first script line would be for f in $(find -iname "*.jpg") $(find -iname "*.png") $(find -iname "*.jpeg"); do. This also allows the files to be in subdirectories, though it would be a lot more complicated if there are blanks in any of the directory or file names. – AFH Sep 16 '14 at 14:11
  • 1
    @AFH yes and no. That will break if the files contain whitespace which is why a glob is preferred. If you use find, you should at least combine it with -print0 and while IFS= read -d''. – terdon Sep 16 '14 at 16:03

ls | grep "png" | awk 'BEGIN{FS="\."}{print $1".png " $1".jpg"}'|xargs mv

Obvs you have to change the first part before the awk to find your png files. And this won't work if you have more than 1 . in the path.

This probably is not a solution that will work in your specific case right away, but there are all the pieces you need. If you give me more details or better yet a printout of a list of all the files you need to be changed, then I could change the command to suit you exactly.

EDIT #1: I didn't realize that he needed to examine the file contents to know which are wrong, i thought he knew the list of incorrectly named files.

EDIT #2: Commenters seem to be obsessing with the part of the code before the awk. I thought I was clear enough with my first sentence, but since I wasn't; You will have to provide the code before the awk that will appropriately list your files. Furthermore, this was intended as a basic example of how you could get started accomplishing a task like this yourself. I admitted it almost certainly wasn't going to work by you copying and pasting.

You will learn more by completing and working through the actual solution yourself than by blindly applying lines from the internet. If you are still stuck from this point feel free to comment and I can try to help.

  • 1
    1. Do not parse ls! 2. You completely misunderstood the question. – jimmij Sep 16 '14 at 13:16
  • I was assuming he knew which needed to be switched, not that he needed to open them to know. what do you mean don't parse ls? – Carlos Bribiescas Sep 16 '14 at 13:18
  • 1
    mywiki.wooledge.org/ParsingLs – jimmij Sep 16 '14 at 13:18
  • Yes, this does break if you put new lines in your filenames... – Carlos Bribiescas Sep 16 '14 at 13:23
  • 1
    Or spaces, or backslashes, or tabs, or file names that contain png... – terdon Sep 16 '14 at 15:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.