2

I've got around 360 000 files like:

./001/1/1.jpg
./001/1/2.jpg
./001/2/1.jpg
./002/1/1.jpg
./003/1/1.jpg
...
pattern: [60 dirs]/[1000 subdirs]/[4-10 files].jpg

I want to rename files using rename for example from *.jpg to *.jpeg. I can't do it with single rename, because I get the error argument list is too long.

Searching for solution, I figured out this, but it renames nothing:

find -maxdepth 2 -mindepth 2 -type d -exec rename -n 's/jpg/jpeg/' {}/* \;

When I check if the {} is expanded replacing rename with echo:

find -maxdepth 2 -mindepth 2 -type d -exec echo "rename -n 's/jpg/jpeg/' {}/*" \;

I get expected result:

rename -n 's/jpg/jpeg/' ./061/61430/*
rename -n 's/jpg/jpeg/' ./061/61431/*
...

If I run any of these rename commands, I rename works. So the should be problem with the {}.

Thank you for help!

  • and if try to escape: \{\}? – fredtantini Jan 6 '15 at 11:23
3
find  | prename 's/\.jpg$/.jpeg/'

or if you have oder files in the currunt directory

find 0[0-9][0-9] | prename 's/\.jpg$/.jpeg/'
  • It doesn't really work but it made me remaking the script so now the problem is solved. Thank you. – koubic Jan 6 '15 at 12:32
  • 1
    @koubic, successfully remaking your own script is even better than a working suggested solution! What is the problem of this version? – JJoao Jan 6 '15 at 14:00
  • Ok, I'm sorry, it actually works. It's just a different approach to my original question. Your approach is slower, because rename process has to be run for every single file. My approach wanted to put a subdirectory to rename so rename would be executed severalfold less often. But I eventually used it because speed wasn't a problem on the real server. – koubic Jan 7 '15 at 13:50
  • @koubic, thank you for everything. In my approach, rename process should be executed only once. If you can, it would be interesting to "time" the solutions (I'm curious about the time taken for renaming such a big number of files!) – JJoao Jan 7 '15 at 15:07
  • This, unfortunately, won't work correctly if any of the filenames contain a newline. A workaround is to use -print0 with find for NUL-separated output and run prename (with full path specified) using perl -0 - e.g. find -print0 | perl -0 /usr/bin/prename 's/\.jpg$/.jpeg/'. prename itself should (but doesn't) have a -0 option...I've reported this as a bug to rt-cpan.org. – cas Feb 13 '18 at 23:01
4

In the first instance, * is expanded by the shell before it gets to rename (if it is expanded at all - I doubt anything matches {}/*), and if it isn't expanded, the command that is executed is rename with the three arguments -n, s/jpg/jpeg/ and some/path/*. That last argument is not the name of an existing file so rename does nothing.

Without shell globbing, the path is useless to rename.

So, instead, do:

find -maxdepth 3 -mindepth 3 -type f -iname '*.jpg' -exec rename -n 's/jpg$/jpeg/i' {} +

Use find's ability to build command lines as long as is possible with + instead of ;.

1

Here is an alternative way should rename happen to be missing:

find 0[0-6][0-9] -name "*.jpg" -exec sh -c 'for i do echo mv "$i" "${i%g}eg"; done' sh {} + 
0

You should not specify type d unless you want to rename only directories. To change extensions .jpg to .jpeg try

find . -maxdepth 2 -mindepth 2 -name '*.jpg' -exec sh -c 'echo mv -- "$0" "${0%%.jpg}.jpeg"' {} \;

Remove echo if you like what you see on the screen.

0

Using cygwin, my version of rename does not have the regex replacement, nor does its rename [options] expression replacement file... syntax seem to work. Also, the bash suggestions fail with

... -c: line 0: unexpected EOF while looking for matching `"'
... -c: line 1: syntax error: unexpected end of file

Alas... there is always perl:

perl -MFile::Find -e 'find(sub{return unless /^(.*)\.jpg$/;`mv $_ $1.jpeg`}, ".")'
  • The rename mentioned in many of these answers is written in perl. See tips.webdesign10.com/files/rename.pl.txt for one implementation. – roaima Jul 1 '16 at 22:27
  • @roaima, how do you know that? On my system (the latest cygwin), the rename found in my default path is "The rename command is part of the util-linux package and is available from ftp.kernel.org/pub/linux/utils/util-linux" and is a binary file, not a perl script... – Lucas Jul 3 '16 at 22:58
  • I also have Cygwin on a number of Windows platforms. There are two different implementations of rename and yours as described is the "other" one. – roaima Jul 3 '16 at 23:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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