Issue
I'm seeking an elegant CLI way to zero-pad filenames that are numbered alpha-numeric strings of an arbitrary length, and which have dashes in place of spaces.
E.g. I would like the following list of files:
1-file-name-of-one-length.mp3
2-shorter-file-name.mp3
3-really-really-really-long-file-name.mp3
> ..
10-another-file-name.mp3
To become:
01-file-name-of-one-length.mp3
02-shorter-file-name.mp3
03-really-really-really-long-file-name.mp3
> ..
10-another-file-name.mp3
I've spent a day learning about awk, bash and rename approaches to zero-padding, but previous questions here and tutorials I've found seem to assume either a purely numerical or a standardised-length file-naming scheme. In such cases the fields between the '-' delimiters can be broken down and re-assembled in a predictable ways with e.g. awk. My strings are of unknown length, so contain an unknown number of fields between the '-' characters.
I'm envisioning the answer will be a 'for loop'. The logic of what I want the loop to do is something like: Read file name to the first '-' character. Determine if the number preceding the first '-' is a single or double-digit number. If it is a single digit number, insert a '0' character in front of it.
EDIT FOR ANSWER
Renaud pointed out the correct syntax for a simple for-loop (my own attempt along these lines had resulted in padding of double-digit numbers too, but Renaud's code worked)
for f in [0-9]-*.mp3; do mv "$f" "0$f"; done
Solution
To pad with one 0 only:
for f in [0-9]-*.mp3; do mv "$f" "0$f"; done
In case there could be no files matching the [0-9]-*.mp3
pattern it is probably better to also use the nullglob
option (in a subshell just to automatically restore the nullglob
status afterwards):
( shopt -s nullglob; for f in [0-9]-*.mp3; do mv "$f" "0$f"; done )
If you want the leading number on n
digits instead of just 2, say 3:
(
n=3
shopt -s extglob nullglob
for f in +([0-9])-*.mp3; do
printf -v g '%0*d-%s' "$n" "${f%%-*}" "${f#*-}"
mv "$f" "$g"
done
)
Finally, if you do not know the value of n
, want to automatically compute it, and assuming it must be the maximum number of leading digits in these file names:
(
shopt -s extglob nullglob
n=0
for f in +([0-9])-*.mp3; do
g="${f%%-*}"
(( n = "${#g}" > n ? "${#g}" : n ))
done
for f in +([0-9])-*.mp3; do
printf -v g '%0*d-%s' "$n" "${f%%-*}" "${f#*-}"
mv "$f" "$g"
done
)
Answered By - Renaud Pacalet Answer Checked By - Mildred Charles (WPSolving Admin)