Rename a bunch of PNG images with ".jpg" extension to ".png"
Asked Answered
G

6

9

So I have a folder with thousands of image files, all of them saved as .jpg.

The problem is that some of those files are actually PNG image files, so they don't open in a lot of programs, unless I manually change their extension to .png. For example, the Ubuntu image viewer throws this error:

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

I've already ran a hexdump of some of these files to confirm this error and it checks out.

I'm looking for a simple way to find all the files with the wrong extension among the other files and change their extension. How would I do this with a bash script for example? So far I have no idea. All help apreciated!

Gentlefolk answered 6/6, 2015 at 15:54 Comment(0)
D
13
for f in *.jpg ; do
  if [[ $(file -b --mime-type "$f") = image/png ]] ; then
    mv "$f" "${f/%.jpg/.png}"
  fi
done

This gets a list of .jpg files, then for each calls the file utility on it to get the mime type. If that's image/png, then it renames the file using a string manipulation substitution.

Dressler answered 6/6, 2015 at 16:8 Comment(0)
M
2

Use file (1) to determine the type of all files. Use grep (1) to filter this list, removing all proper JPEG files. What remains is a list of files that cannot be recognized as a JPEG.

In a single line

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

– make sure to verify that JPEG image data indeed is what file returns on a correctly identified JPG file.

You can use sed (1) to remove the stuff after the colon : and end up with the file name only:

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

.. which is the end of my bash-fu. At this point I'd store the resulting list in a file (add > list) and use GREP in a text editor to rewrite all lines to a proper rename command, then run that.

Mcgough answered 6/6, 2015 at 16:17 Comment(0)
B
1

You want to use file and parse the output. You can check if it's a JPEG or a PNG by checking the initial part of the output:

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

You can change the extension by stripping the .jpg with basename. For example, the following will change the extension of the file $F with extension .jpg to .png:

mv $F $(dirname $F)/$(basename $F .jpg).png
Bushman answered 6/6, 2015 at 16:3 Comment(0)
T
1

Firstly get a list of files and make them in a file. Then process the list to a loop so that you can change files one by one automatically.

#!/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
Through answered 6/6, 2015 at 16:5 Comment(0)
A
0

I am not sure of the appropriate commands for a bash script but you could easily write a C++ file to try to open these files and catch the error. The files that you catch the error will not be the appropriate type (assuming that's your only issue). If you know those incorrect file types should be PNG, you can rename the file. Something like the pseudocode:

For (ALL_FILES)
{
  try 
  {
    open(FILENAME);
  }
  catch
  {
    rename(FILENAME, NEW_FILENAME);
  }
}
Angloirish answered 6/6, 2015 at 16:1 Comment(1)
This assumes the open attempts to parse the file data and that it relies on the file extension to be correct. A simple 'generic' open will always succeed on an existing file. A 'smart' open will ignore the file extension and use the file's magic signature to determine its type and may therefore succeed.Mcgough
H
0

I found this to be the easiest method, it will also change all the file in the sub directory

find . -name "*.jpg" -type f -exec rename 's/\.jpg$/.png/' \{} \;

Heretofore answered 9/12, 2022 at 1:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.