I have a folder with many thousands of files, which due to an error had their extensions misnamed, all files now have the .jpg extension.

In all the .jpg files I would like to find the non-image files.

Is there a command-line way to identify which files are an actual image and which files are not?

I thought of looking for files without a preview, but cannot find a way to search files without a preview.

Here's an axample file that has a .jpg extension, but is not a real image:

enter image description here

  • 1
    One more reason why file name extensions should not be used to control what type of file a file is. – Glen Yates Nov 24 '20 at 17:22
  • 3
    @GlenYates technically, they don't. The extension is what is used by OSes to determine what file handler to use. That's really all. – Logarr Nov 24 '20 at 21:49
  • @Logarr Exactly because they don't control what a file actually is, what I meant to convey was that file extensions should not be used by OSes to determine file associations. Not all OSes use file extensions for this. – Glen Yates Nov 24 '20 at 21:56
  • 1
    @GlenYates I'd rather have predictable behaviour based on file name extensions than the mess that could otherwise result. See, for example: Does X-Content-Type-Options really prevent content sniffing attacks? and this answer to "Using file extension and MIME type (as output by file -i -b) combination to determine unsafe files?". – Brian Drake Nov 25 '20 at 15:12
  • @GlenYates If you can invent a better method, I'm sure you could make a lot of money licensing that method to Microsoft and Apple, because that would be quite a paradigm shift in OS user interface design. – TylerH Nov 25 '20 at 19:44

You can use file FILENAME to determine the type of data in a file.

$ file image.jpg text.jpg pdf.jpg
image.jpg: JPEG image data
text.jpg:  ASCII text
pdf.jpg:   PDF document, version 1.4

So, file *.jpg | grep -v JPEG should give a list of all non-JPEGs with the ".jpg" extension

Also, assuming there are PDFs you can rename them in one go

find . -type f \
    -exec sh -c 'file "$1" | grep -q PDF' _ {} \;  \
    -exec sh -c 'echo mv -- "$1" "${1%%jpg}pdf"' _ {} \;

Remove the echo in the second line once you verified that the output looks ok.

  • 10
    And specific to this question, file *.jpg|grep -v JPEG should give a list of all non-JPEGs with the ".jpg" extension. – Mark Nov 23 '20 at 22:49
  • @Mark Thanks, that was indeed missing from the answer :-) – nohillside Nov 24 '20 at 7:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .