Using only standard tools (bash
, mv
, date
)
Add a variable that counts up with each loop iteration. Then use printf
to add the leading zeros.
#! /usr/bin/env bash
c=1
for f in *; do
mv -n "$f" "${prefix}_$(date -r "$f" +%Y%m%d)_$(printf %05d "$c").${f#*.}"
(( c++ ))
done
Here we used a fixed width of five digits for the sequence number. If you only want to use as few digits as required you can use the following approach:
#! /usr/bin/env bash
files=(*)
while read i; do
f="${files[10#$i]}"
mv -n "$f" "${prefix}_$(date -r "$f" +%Y%m%d)_$i.${f#*.}"
done < <(seq -w 0 "$((${#files[@]}-1))")
This will use 1-digit numbers if there are only up to 9 files, 2 digits if there are only 10 to 99 files, 3 digits for 100 to 999 files, and so on.
In case you wonder about the 10#$i
: Bash interprets numbers with leading zeros as octal numbers, that is 010 = 8 and 08 = error. To interpret the numbers generated by seq -w
correctly we specify the base manually using the prefix 10#
.
Using a dedicated tool
For bulk renaming files, you don't have to re-invent the wheel. Install a tool like rename
/perl-rename
/prename
and use something like
perl-rename '$N=sprintf("%05d",++$N); s/(.*)(\.[^.]*)/$1$N$2/' *
Here I skipped the date
part, because you never showed the original names of your files. A simple string manipulation would probably sufficient to convert the date to YYYYMMDD
format.