11

My photo importer moved files from my camera and renamed them, but I forgot to specify that it should keep the file extension. So I have several folders with hundreds of JPG & AVI files that are all missing their proper extension.

There aren't that many video files so I can manually rename them either before of after a general mass-rename to JPG.

To make things more complicated, the filenames contain spaces, so I can't just mv "*" "*.jpg" because, well, that doesn't work (but that's what I'd do, coming from DOS/Windows).

I know Linux is full of powerful commands. How can I mass-rename files to add a .jpg extension, when those files contain spaces?

Please don't say "don't use spaces" because that's really not what I'm asking about. Thanks.

1
  • Okay, I won't tell you to use spaces, but if you change your mind later try find /PATH/TO/FOLDER -depth -name "* *" -execdir rename 's/ /_/g' "{}" \; (source) which will replace all spaces in files & folders & subfolders for you. Jun 19, 2014 at 15:45

6 Answers 6

23

Shell globs should work even with spaces in the names if used properly e.g.

rename -nv -- 's/$/.jpg/' *

or

for file in *; do echo mv -- "$file" "$file.jpg"; done

[NOTE: these are 'no ops' until the n switch or the echo are removed - so you can check the correct replacement before committing]

If you do want to automatically distinguish between jpg and avi files that would also be possible using a more complex loop and the file or mimetype command

6
  • 1
    +1 but note that 1) this will also rename directories and 2) it does not recurse which I think the OP needs since they have "multiple directories".
    – terdon
    Jun 19, 2014 at 15:19
  • 1
    Recursion is not important, but it's a good observation. I love the way you built this as a demo-then-true model. Jun 19, 2014 at 17:31
  • Thanks but you should look at @terdon's answer as a more general (and more robust) solution. Jun 19, 2014 at 18:52
  • @steeldriver You should probably specify which rename you are using. This is the one that comes with perl, not the more common and less useful one which comes with util-linux
    – user234837
    Jun 20, 2014 at 6:00
  • @BroSlow fair point but the Ubuntu (and Debian) default rename is the perl one. The one from util-linux is /usr/bin/rename.ul on Ubuntu while /usr/bin/rename is by default a symlink to /usr/bin/prename. In general in the Debian world (and this is Ask Ubuntu) it is safe to assume prename unless otherwise stated.
    – terdon
    Jun 21, 2014 at 11:52
9

If you have a more complex hierarchy, you'll need a slightly more sophisticated approach. You can either use bash's globstar option which lets ** match zero or more directories and subdirectories or you can use find.

  1. globstar

    shopt -s globstar
    for f in **/*; do [ -f "$f" ] && mv "$f" "$f".jpg; done
    

    The [ -f "$f" ] & ensures that the mv command is only run on files and not directories.

  2. find

    find . -type f -print0 | xargs -0 -I{} mv "{}" "{}".jpg
    

    The -type f ensures we only find files and no directories and the print0 causes find to print its output separated with the null character (\0) instead of newlines. This ensures that we deal correctly with file names containing spaces or newlines or other weirdness.

    xargs takes a list of input and runs the command given on it. The -0 flag tells it to expect null-separated input and the -I{} will make it replace each instance of {} with each of the input records (files in this case) passed.

2
  • Thank you for showing "The Linux Way." This find method turns out to be quite flexible.
    – Ray Foss
    Jan 21, 2018 at 5:21
  • To make the extension capitalized without appending, using a similar technique, assuming no files are named with a %: find -name *.jpg -print0 | xargs -0 -I{} sh -c "printf \"'{}' \" && printf \"'{}\" | head -c-4 && printf \".JPG'\0\"" | xargs -0 -I{} sh -c "mv {}"
    – Ray Foss
    Jan 21, 2018 at 6:05
6

Please refer to man rename before you try this

This should work like a charm.

In a terminal:

cd /path/to/exported/imgs/folder/
rename  's/(\w+)$/$1\.jpg/' *

Please change "jpg" to whatever you need.

rename can use perl expresions.. your best friend

At first line you entered your files directory

cd /path/to/exported/imgs/folder/

The s the before expresion indicates a substitution

rename  's/(\w+)$/$1\.jpg/' *

Then will search for any file with an alphanumeric and underscore name , but without extension

rename  's/(\w+)$/$1\.jpg/' *

And replace add to it . a dot jpg

rename  's/(\w+)$/$1\.jpg/' *

Finally apply to any file in first line folder

rename  's/(\w+)$/$1\.jpg/' *
0
4

I would advise you use a program called pyrenamer.

Open it, and in the Renamed file name pattern, enter {1}.jpg.

1
  • Very easy and worked like charm
    – Kendor
    Oct 5, 2015 at 21:54
3

I encounter this situation quite often administering systems, especially when dealing with filenames created by windows applications. To add .jpg extensions on filenames without any extension, consider this command list.

find ./example -type f -name '*' -print0 | xargs -0 -I'{}' mv '{}' '{}'.jpg

find's -print0 generates NULL characters for separators, xargs's -0 is for accepting those NULL separators. This will also do this for any subdirectories, so be sure to replace that './example' path.

rename is a great command, but it's distro specific in both implementation and specification. I generally use things like rename on the command line, but I always write in GNU utils standards for my scripts.

2

Use this command:

rename  's/$/.jpg/' *
1

You must log in to answer this question.

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