133

I have a few directories and sub-directories containing files with no file extension. I want to add .jpg to all the files contained within these directories. I've seen bash scripts for changing the file extension but not for just adding one. It also needs to be recursive, can someone help please?

robjmills
  • 18,438
  • 15
  • 77
  • 121

6 Answers6

287

Alternative command without an explicit loop (man find):

find . -type f -exec mv '{}' '{}'.jpg \;

Explanation: this recursively finds all files (-type f) starting from the current directory (.) and applies the move command (mv) to each of them. Note also the quotes around {}, so that filenames with spaces (and even newlines...) are properly handled.

Stephan202
  • 59,965
  • 13
  • 127
  • 133
  • 7
    In particular, this one works better if there are a huge number of files in the directory structure (causing bash to get upset about the length of the list of files to iterate over). – DrAl Jul 10 '09 at 09:17
  • @Al, if you refer to a `for` loop upsetting bash to iterate over a list of files, that is not correct. The bash `for` loop iteratively issues each `mv` command. – nik Jul 10 '09 at 10:00
  • Question: Does `find` first set up a list of files *before* it executes the `-exec` statement? I guess so, but want to get this point clear before coding infinite loops. – Boldewyn Jul 10 '09 at 10:08
  • @Boldewyn, I think it will be prudent to avoid working on symbolic links (with a `-P`) if you suspect a possible loop. – nik Jul 10 '09 at 10:19
  • Though, symbolic links are skipped by default I think. – nik Jul 10 '09 at 10:20
  • 2
    this command will find files with extension as well. Is that what OP wants? – ghostdog74 Jul 10 '09 at 11:27
  • 2
    @ghostdog74: Since he accepted this answer, the above apparently did the trick. Otherwise, as you mentioned below, adding `-not -name "*.*"` will do the trick. – Stephan202 Jul 10 '09 at 11:49
  • In my version of bash, the quotes around {} have no effect on how "find" handles filenames with spaces, etc around them. As you've written it, the "find" command will not even see the quotes: they're handled by bash – Adrian Pronk Jul 12 '09 at 22:36
  • I get this following error while doing this .. find: missing argument to `-exec' – ArunMKumar Jul 04 '14 at 10:05
  • luckily I found out *not* the hard way that this is *very* dangerous with git. find doesn't care that .git is hidden on purpose and will add that extension to all the internals of that git repo! meaning you have to remove all of the added extensions to all the .git folder which can be just as crazy a task as this might have originally been. – gabeio Feb 03 '15 at 08:43
  • using this to generate `.sample` versions of config files :) – scones Jul 26 '16 at 16:18
72

this will find files without extension and add your .jpg

find /path -type f -not -name "*.*" -exec mv "{}" "{}".jpg \;
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
10

This is a little late, but I thought I would add that a better solution (although maybe less readable) than the ones so far might be:

find /path -type f -not -name "*.*" -print0 | xargs -0 rename 's/(.)$/$1.jpg/'

Using the find | xargs pattern generally results in more efficient execution, as you don't have to fork a new process for each file.

Note that this requires the version of rename found in Debian-flavored distros (aka prename), rather than the traditional rename. It's just a tiny perl script, though, so it would be easy enough to use the command above on any system.

canadian_scholar
  • 1,315
  • 12
  • 26
Chad Huneycutt
  • 201
  • 1
  • 4
7

like this,

for f in $(find . -type f); do mv $f ${f}.jpg; done

I am not expecting you have space separated file names,
If you do, the names will need to be processed a bit.

If you want to execute the command from some other directory,
you can replace the find . with find /target/directory.

nik
  • 13,254
  • 3
  • 41
  • 57
2

For renaming all files with no extension in Windows basic you can do ren * *.jpg Since the file as no extension, just use the *, or if you want to change png to jpg use ren *.png *.jpg

rayryeng
  • 102,964
  • 22
  • 184
  • 193
Nuno
  • 41
  • 2
0

rename

not sure that it can rename files without extensions (I'm on windows 7 right now)

dfa
  • 114,442
  • 31
  • 189
  • 228
  • 1
    it can, but it will also rename directories, and there is no way to tell it to work recursively in sub-directories (at least with the version I have on Ubuntu). – mirod Jul 10 '09 at 09:42
  • I know at least of two different commands called `rename`, one a C program included in util-linux-ng and one a Perl program (by Wall himself) on our university's Debian machines. Actually, none of both do recursion. – Boldewyn Jul 10 '09 at 10:11