116

What is the good way to add file extension ".jpg" to extension-less files with bash?

2
  • 4
    mv "${file}" "${file}.jpg" ?
    – onteria_
    Commented May 24, 2011 at 16:57
  • 2
    in your view, what is an "extension-less file"? Is it a file without a dot in the name? Commented May 24, 2011 at 17:08

10 Answers 10

154
# Strip .jpg from all filenames
for f in *.jpg; do mv "$f" "${f%.jpg}"; done
# Add .jpg to all filenames (even those with .jpg already)
for f in *; do mv "$f" "$f.jpg"; done
# Add .jpg to all filenames...unless they are already .jpg
for f in *; do case "$f" in *.jpg) echo skipped $f;; *) mv "$f" "$f".jpg; esac; done
# Add .jpg to all filenames...unless they already have a . extension
for f in *; do case "$f" in *.*) echo skipped $f;; *) mv "$f" "$f".jpg; esac; done
5
  • 10
    second one is perfect for renaming extensionless files! thanks! Commented Sep 9, 2014 at 3:33
  • 5
    second one adds an extension on all files, not just extensionless ones
    – Jeff
    Commented Mar 24, 2015 at 15:55
  • 6
    just as a note "${f%.jpg}" is bash shell string manipulation. ` ${string%substring}` Deletes shortest match of $substring from back of $string.
    – Jichao
    Commented Aug 28, 2015 at 19:36
  • 2
    Warning: If you have a folder with mixed extensions, know that the above adds .jpg to even normal files.
    – sachinruk
    Commented Oct 27, 2016 at 23:51
  • 1
    Can we check if its already ended with .jpg? to prevent adding additional .jpg to the end
    – alper
    Commented Sep 29, 2021 at 14:01
68

You can use rename:

rename 's/(.*)/$1.jpg/' *
4
  • 3
    which version of rename are you using? Mine has different arguments: rename from to file...
    – B Johnson
    Commented May 24, 2011 at 17:31
  • 1
    rename is included with perl, which is version 5.10.1.
    – Kim Stebel
    Commented May 24, 2011 at 17:58
  • 3
    This works great with the rename included in Ubuntu (and so I'm guessing all Debian based distros), much less verbose than jm666's answer. Commented Jun 10, 2012 at 10:59
  • 1
    Beware that there isn't a single rename tool: oylenshpeegul.typepad.com/blog/2011/12/…
    – waldyrious
    Commented Nov 18, 2021 at 17:02
30

Another way - without loops

find . -type f -not -name "*.*" -print0 |\
xargs -0 file |\
grep  'JPEG image data' |\
sed 's/:.*//' |\
xargs -I % echo mv % %.jpg

Breakdown:

  • find all files without extension
  • check the file type
  • filter out only JPG files
  • delete filetype info
  • xargs run the "mv" for each file

the above command is for dry run, after it you should remove the "echo" before mv

EDIT Some people suggesting that here is needed "Wrap path arguments in quotes; avoids argument splitting on paths with spaces".

Usually, this recommendation is true, in this case isn't. Because, here the % is got replaced not by shell expansion but by the xargs internally (directly), so the % will be substituted correctly even with spaces in filenames.

Simple demo:

$ mkdir xargstest
$ cd xargstest

# create two files with spaces in names
$ touch 'a b' 'c d'

$ find . -type f -print
./c d
./a b
# notice, here are spaces in the above paths

#the actual xargs mv WITHOUT quotes
$ find . -type f -print | xargs -I % mv % %.ext

$ find . -type f -print
./a b.ext
./c d.ext
# the result is correct even in case with spaces in the filenames...
3
  • You can put this into a loop and this xargs are superfluous. I like Ryan's answer better in this situation.
    – Lucius
    Commented May 24, 2011 at 19:51
  • 1
    @Lucius - btw, the question want "extensionless" files - so Ryan should find only those...
    – clt60
    Commented May 24, 2011 at 20:12
  • @jm666 hey! how do I modify your code snippet to rename all extensionless files in a folder to their respective extensions. (I am detecting correct extensions by file -b $filename command.)
    – Soumyajit
    Commented Jan 10, 2016 at 16:44
26

Simple, cd to the directory where your files are and:

for f in *;do mv $f $f.jpg;done
3
  • For some reason this works for me, but Seth's solution with quotes doesn't. (OSX Mountain Lion bash)
    – delrocco
    Commented Dec 18, 2016 at 14:36
  • 5
    Would be better if used for f in *;do mv "$f" "$f".jpg;done to support spaces in filenames.
    – Hritik
    Commented Jun 22, 2017 at 17:09
  • Thanks for this elegant and simple solution -- I have landed on this answer multiple times, but can't seem to memorize it. #dejavu Commented Jan 30, 2019 at 18:11
19

dry run:

 rename -n s/$/.jpg/ *

actual renaming:

 rename s/$/.jpg/ *
1
6
find . | while read FILE; do if [ $(file --mime-type -b "$FILE") == "image/jpeg" ]; then mv "$FILE" "$FILE".jpg; fi; done;
1

In my case i was not aware of the filetype so i used the mv command with the help of the file command to examine and possibly find the file type. This solution might not be perfect for all files since the file command might not recognize the filetype but it worked mostly good for me.

for f in *; do ext=$(file $f | awk '{print $2;}'); mv -n "$f" "$f.$ext"; done

The use of awk is to strip the second word of the string returned from the command file that is actually the extension.

1
  • handles jpg and png automatically. used it and works - thanks a lot! Only now extensions are CAPS. small problem though :)
    – krivar
    Commented Jul 14, 2020 at 13:12
0
rename --dry-run * -a ".jpg" # test  
* -a ".jpg" # rename
2
  • --dry-run and -a are not available in my version of rename. If this is specific to some architecture it should be specified. Commented Apr 9, 2017 at 9:59
  • 1
    As @FernandoCésar alludes to, there isn't a single rename tool, so the syntax may vary in different systems. See oylenshpeegul.typepad.com/blog/2011/12/… for more information.
    – waldyrious
    Commented Nov 18, 2021 at 17:04
0

You can use move multiple files. I am a maintainer of this project. The syntax is simple.

mmf files*

It will open your $EDITOR with all files names, or vim by default and you can simply highlight the end of all file names using Ctrl+v+G in vim , save the file,quit and that it , all your files are renamed

-3

Ryan Li

The correct syntax for adding a file extension to multiple files within a directory which do not have a file extension is

find . | while read FILE; do if [[ -n `file --mime-type "$FILE" | grep 'message/rfc822'` ]]; then  mv "$FILE" "$FILE".eml; fi; done;

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