Rename files to change punctuation and numbering

filesrenamescripting

I need a command to recursively rename a large number of jpg files in Ubuntu.

However there are some problems. A normal group of files would look like ani-estate-villas_1431640729_3.jpg, ani-estate-villa_3627544278_7.jpg and ani-estate-villa_3143254376_5.jpg

I need to replace all - with _, remove all numbers and then add numbering which resets in every directory. So the same group of files should look like ani_estate_villas_1.jpg, ani_estate_villas_2.jpg, ani_estate_villas_3.jpg and the same with the other files in the other directories.

The depth of the recursion is 1 or 2 directories deep, so you might find a directory/file.jpg or directory/directory/file.jpg it's pretty much random.

Running a command in every directory with jpgs is also doable so if anyone has any idea on how to rename all files with those characteristics would be fine. Although running one single command is cooler, I'd much appreciate a bit more repetitive solution, because manually changing the 400+ jpg files is too much.

I tried using krename but it deletes my files.

Best Answer

You can use the prename command to rename files based on a transformation written in Perl.

Let's start simple. To rename all the .jpg files in a directory, changing all - to _, we can just use the s operator (we could also use tr). The Perl code is executed to transform each file name.

prename 's!-!_!g' *.jpg

To change the number sequence(s) at the end to a simple counter, we introduce a counter variable. I use the global variable $a as a counter (introducing extra variables is more complicated). The regular expression (\.[^/.]*)$ matches the file extension, and $1 in the replacement text stands for what the parenthesized group matched.

prename 's!-!_!g; ++$a; s!_[0-9_]+(\.[^/.]*)$!_$a$1!' *.jpg

Note that the files are renamed in the order given by the file name arguments, i.e. the order of expansion of *.jpg determines the numbering of the files.

Alternatively, we can initialize the counter explicitly with a BEGIN block.

prename 'BEGIN {$a = 1;} s!-!_!g; s!_[0-9_]+(\.[^/.]*)$!_$a$1!; ++$a;' *.jpg

To perform this in every subdirectory of the current directory, call find.

find -type d -exec sh -c 'cd "$1" && prename "$0" *.jpg' 's!-!_!g; ++$a; s!_[0-9_]+(\.[^/.]*)$!_$a$1!' {} \;
Related Question