Home > Software design >  linux command rename dates (YYYY.MMDD) to numbers(001,002,...,066,067) sequentially
linux command rename dates (YYYY.MMDD) to numbers(001,002,...,066,067) sequentially

Time:10-09

I have renamed many files by using 'rename'.

However, I find a problem with conversion dates to numbers.

The file name is 2021.0801, 2021.0802, .. etc. (Year.Month&date)

I need to change Month&date parts to numbers of 001, 002, etc.

So I need to rename

2021.0801
2021.0802
...
2021.0929
2021.0930

to

2021.001
2021.002
...
2021.0**
2021.0**

I saw I can do it when I use rename or #, ? but I could not see the specific way to solve this.

Could you please let me know the way to rename these?

p.s. I tried num=001; for i in {0801..0930}; do rename $i $num *; (($num )); done but it showed

2021.001
2021.001001
2021.001001001001
...

Additionally, ls 2021.* shows only the files that I want to change.

CodePudding user response:

You don't need the for loop. This single command will do it all :

rename -n 'BEGIN{our $num=1}{our $num;s/\d $/sprintf("d", $num)/e; $num  = 1}' 2021.*

Remove -n once the resulting renaming looks good.

CodePudding user response:

Your script contains a few errors. I suggest to use https://www.shellcheck.net/ to check your scripts.

After fixing the errors, the (unfinished) result is

#!/bin/bash
num=001; for i in {0801..0930}; do rename "$i" "$num" ./*; ((num  )); done

This has 3 remaining problems.

  1. The range {0801..0930} includes the numbers 0831, 0832, ... 0899, 0900. This can be fixed by using two ranges {0801..0831} {0901..0930}
  2. The increment operation ((num )) does not preserve the leading zeros. This can be fixed by conditionally adding 1 or 2 zeros.
  3. You call rename for every combination which will check all files and probably rename only one. As you know the exact file names you can replace this with a mv command.

The final version is

num=1; for i in {0801..0831} {0901..0930}; do
  if [[ num -lt 10 ]] ; then
    new="00$num";
  elif [[ num -lt 100 ]] ; then
    new="0$num";
  else
    new="$num"; # this case is not necessary here
  fi;
  mv "2021.$i" "2021.$new";
  ((num  ));
done 

The script handles leading zeros for values of 1, 2 or 3 digits which is not needed here as all numbers are less than 100. For this case, it can be simplified as

num=1; for i in {0801..0831} {0901..0930}; do
  if [[ num -lt 10 ]] ; then
    new="00$num";
  else
    new="0$num";
  fi;
  mv "2021.$i" "2021.$new";
  ((num  ));
done 

The script will execute these commands:

mv 2021.0801 2021.001
mv 2021.0802 2021.002
...
mv 2021.0830 2021.030
mv 2021.0831 2021.031
mv 2021.0901 2021.032
mv 2021.0902 2021.033
...
mv 2021.0929 2021.060
mv 2021.0930 2021.061
  • Related