As you've already discovered, putting our $i = 28;
in the main script doesn't work because it resets $i to 28 for every filename - rename
executes every statement in the main script once for every filename.
You can set an initial value for a variable (or any other setup code that only needs to be run once when the script first executes) in a BEGIN
block - e.g. BEGIN {our $i = 28};
.
You still have to declare the variable as a package global variable with our
in both the BEGIN block and the main script because rename
runs perl code in strict
mode. See perldoc -f our and perldoc strict.
$ rename -n 'BEGIN {our $i = 28};
our $i;
s/_.*/sprintf("_%03d.png", $i++)/e' *.png
rename(abc_128390.png, abc_028.png)
rename(abc_138493.png, abc_029.png)
rename(abc_159084.png, abc_030.png)
Note: you do not have to declare the variable with our
every time you use the variable. Declare it only once in each code block, i.e. once in BEGIN and once in the main script - either before it is first used in a code block, or when it is first used in a block. i.e. this works too:
$ rename -n 'BEGIN {our $i = 28};
s/_.*/sprintf("_%03d.png", our $i++)/e' *.png
Also worth noting: if you need to use a variable that should be reset for every filename, declare it as a local variable with my
rather than our
. See perldoc -f my.
For a contrived example:
$ rename -n 'BEGIN {our $i = 28};
our $i;
my $formatted_number = sprintf("_%03d.png", $i++);
s/_.*/$formatted_number/' *.png
rename(abc_128390.png, abc_028.png)
rename(abc_138493.png, abc_029.png)
rename(abc_159084.png, abc_030.png)
In this version, we don't need the /e
modifier to the s///
operation because we don't need to evaluate the replacement as perl code, just use it as an interpolated variable. See perldoc -f s
One more thing:
Declaring $i
as a state
variable (see perldoc -f state) works too, without needing a BEGIN block but I would recommend avoiding it unless you have a really good grasp of variable scope in perl:
$ rename -n 'state $i = 28;
s/_.*/sprintf("_%03d.png", $i++)/e' *.png
rename(abc_128390.png, abc_028.png)
rename(abc_138493.png, abc_029.png)
rename(abc_159084.png, abc_030.png)
See Persistent Private Variables and Coping with Scoping (which doesn't even mention state
because it was written in 1998 before perl v5.10 when state
was introduced, but is still good reading to understand perl variable scope)