-1

Given a number files named like so:

2016_31_3_03_01c_02
2016_31_3_04_01a_02
2016_31_3_05_01d_02

I want to batch rename them so they read like

2016_31_3_3_1c_02
2016_31_3_4_1a_02
2016_31_3_5_1d_02

I could do rename 's/03_01c/3_1c/' for every file but that would defeat the purpose of batching it.

How do I write the regex for rename command to accomplish this? Something like: rename 's/0{0..9}_01{a..d}/ but I don't know how to write the replace part without also replacing the leading zero after the underscore, which I want to keep.

I also don't really understand the regex to remove the leading zero but keep the digit following the leading zero the same. I know the regex to find those instances but not replace them.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
Bleakley
  • 653
  • 2
  • 9
  • 19

2 Answers2

0

You can use the following regex

~s/\d{4}_\d{2}_\d{1,2}_\K0(\d)_0(\d)/$1_$2/

Or else you can try the following regex also

~s/0(\d)_0(\d\w+)(?=.)/$1_$2/

And the one liner should be

perl -e ' while(glob("*")){(my $newfilename=$_)=~s/0(\d)_0(\d\w+)(?=.)/$1_$2/; rename $_, $newfilename;} '

If you are in linux you can try with ls command (make sure you are in current directory)

ls | perl -ple '(my $newfilename=$_)=~s/0(\d)_0(\d\w+)(?=.)/$1_$2/; rename $_,$newfilename'
mkHun
  • 5,891
  • 8
  • 38
  • 85
0

As long as you're using Linux, all the files are in the current working directory, and all fields of the file names are in decimal except for the fifth, which is in hex, you can use something like this

To actually rename the files, remove the @ARGV = qw/ ... / and uncomment the rename, and call the program something like

perl rename.pl *

rename.pl

use strict;
use warnings 'all';
use feature 'say';
use autodie;

@ARGV = qw/
    2016_31_3_03_01c_02
    2016_31_3_04_01a_02
    2016_31_3_05_01d_02
/;

for ( @ARGV ) {

    my @f = split /_/;
    $_ = hex for $f[4];

    my $new = sprintf('%d_%d_%d_%d_%x_%02d', @f);

    say "$_ => $new";

    # rename $_, $new;
}

output

2016_31_3_03_01c_02 => 2016_31_3_3_1c_02
2016_31_3_04_01a_02 => 2016_31_3_4_1a_02
2016_31_3_05_01d_02 => 2016_31_3_5_1d_02
Borodin
  • 126,100
  • 9
  • 70
  • 144