0

I have a loop that's going through files in a dir and renaming them.

for f in *
   do
      mv -n "$f" "$prefix_$(date -r "$f" +"%Y%m%d").${f#*.}"
   done

I need to append the sequence number at the end, like

TEST_20200505_00001.NEF
TEST_20200505_00002.NEF
TEST_20200505_00155.NEF

How can I go about doing that?

antonpug
  • 13,724
  • 28
  • 88
  • 129
  • 1
    To a veteran user like you I wouldn't normally say this, but looking at your profile it seems like you stopped caring around summer 2013 as you only accepted 5 answers to your 32 questions that received at least one answer since then. So here we go: **Please accept the answer that helped you the most. If none of the answers solved your problem, please add comments or edit your question to point out the problems.** Ignoring all these people who tried to help you is rather disrespectful. – Socowi May 09 '20 at 08:39

1 Answers1

5

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.

Socowi
  • 25,550
  • 3
  • 32
  • 54