'Add leading zeros to integer section of filename
I have folders of images with names like HolidaySnapsJune-1.tif , HolidaySnapsMay-12.tif and HolidaySnaps2018-005.tif
I want to add one leading 0 to the integer section of the filename if it is 2 digits long, and I want to add two leading 00s if it is just one digit long.
I have tried variations of
find . -name '*\_[0-9][0-9].tif' -exec sh -c '
for fpath do
echo mv "$fpath" "${fpath%/*}/${fpath##*/}"
done' _ {} +
But these put the leading zeros in front of the full file name instead of in front of the integer section.
I would love to do this is a bash script which would recursively work on folders so it's important that the difference in names preceeding the '-' is ignored or worked-around.
I'm on Windows and just have access to whatever is built into git-bashso bash, sed, awk etc.
Solution 1:[1]
You could use the rename.ul command from linux-utils.
rename [options] expression replacement file...
replaces the first occurence of expression by replacement in all names of files passed to the command.
Assuming your filenames contain exactly one hyphen -, you could simply run both of the following commands in a shell that supports the **/* glob syntax (alternatively, use find with the -exec option or something alike) to recursively rename all files:
rename.ul -- - -00 **/*-?.tif
rename.ul -- - -0 **/*-??.tif
There are several options to rename.ul to prevent you from accidentally renaming unintended files (Watch out! The consequences could be quite drastic):
-v, --verbose
Show which files were renamed, if any.
-n, --no-act
Do not make any changes; add --verbose to see what would
be made.
-i, --interactive
Ask before overwriting existing files.
So you could either run the commands with the -nv options to perform a dry-run and see what changes the program would make, or add -i to be asked for confirmation each time a file would be renamed.
Solution 2:[2]
If you don't want to use non-standard commands and write a small script, this would be one way to do it.
while read -r line; do
num=$(sed 's/\..*//' <<<${line/*-})
printf -v new_name '%s-%03d.%s' "${line/-*}" "${num}" "${line/*\.}"
mv -v "${line}” "${new_name}"
done < <(printf '%s\n' HolidaySnapsJune-1.tif HolidaySnapsMay-12.tif)
Using HolidaySnapsJune-1.tif for explanation below:
${line/*-}removes everything before the dash-=1.tif${line/*\.}removes everything besides the extension.sed 's/\..*//' <<<${line/*-}also removes everything after the first period., so now we have simply1'%s-%03d.%s'the%03dpart of that tells printf to print digits with leading zeroes up to 3 digits.
Used while read as it is easy to mockup with. You probably want to either use a find command or something such for the input to the loop.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Kaffe Myers |
