I need to batch rename 40000 files on a folder with a number count in the end like this:. something.jpg to something_00001.jpg. I\'d like to work with the rename command, but an
These are powerful commands that will make lots of changes very rapidly - please test on a copy of a small subset of your data.
Method 1 - Using "rename" (Perl tool)
This should work with rename
which you can install on macOS with:
brew install rename
The command would be:
rename --dry-run -N "00001" 's/.jpg$/_$N.jpg/' *jpg
Remove the --dry-run
to actually execute the command rather than just tell you what it would do.
Method 2 - Using GNU Parallel
Alternatively, this should work with GNU Parallel which you can install on macOS with:
brew install parallel
The command would be:
find . -name \*.jpg -print0 | parallel -0 --dry-run mv {} {.}_{#}.jpg
where:
{}
means "the current file",{.}
means "the current file minus extension", and{#}
means "the (sequential) job number"Remove the --dry-run
to actually execute the command rather than just tell you what it would do.
You mentioned you wanted an offset, so the following works with an offset of 3:
find . -name \*.jpg -print0 | parallel -0 'printf -v new "%s_%05d.jpg" "{.}" $(({#}+3)); echo mv "{}" "$new"'
Method 3 - No additional software required
This should work using just standard, built-in tools:
#!/bin/bash
for f in *.jpg; do
# Figure out new name
printf -v new "%s_%05d.jpg" "${f%.jpg}" $((cnt+=1))
echo Would rename \"$f\" as \"$new\"
#mv "$f" "$new"
done
Remove the #
in the penultimate line to actually do the rename.
Method 4 - No additional software required
This should work using just standard, built-in tools. Note that macOS comes with Perl installed, and this should be faster as it doesn't start a new mv
process for each of 40,000 files like the previous method. Instead, Perl is started just once, it reads the null-terminated filenames passed to it by find
and then executes a library call for each:
find . -name \*.jpg -print0 | perl -0 -e 'while(<>){ ($sthg=$_)=~s/.jpg//; $new=sprintf("%s_%05d.jpg",$sthg,++$cnt); printf("Rename $_ as $new\n"); }'
If that looks correct, change the last line so it actually does the rename rather than just telling you what it would do:
find . -name \*.jpg -print0 | perl -0 -e 'while(<>){ ($sthg=$_)=~s/.jpg//; $new=sprintf("%s_%05d.jpg",$sthg,++$cnt); mv $_, $new; }'
Here's a solution using renamer.
$ tree
.
├── beach.jpg
├── sky.jpg
$ renamer --path-element name --index-format %05d --find /$/ --replace _{{index}} *
$ tree
.
├── beach_00001.jpg
├── sky_00002.jpg