命令行中的Perl表达式 - 重命名文件

时间:2015-11-24 12:56:14

标签: perl shell rename local-variables

有人能解释our吗?

的出现
ls -1 | grep .ppm | xargs rename -n 's/.*/our $i; if(!$i) { $i=1; } sprintf("%03d.jpg", $i++)/e'

我尝试更改our其他任何内容,(opti,此处),

ls -1 | grep .ppm | xargs rename -n 's/.*/opti $i; if(!$i) { $i=1; } sprintf("%03d.jpg", $i++)/e'

抛出以下错误:

 Global symbol "$i" requires explicit package name at (user-supplied code).

2 个答案:

答案 0 :(得分:2)

看起来它允许您在当前重命名操作的范围内重用全局变量$i

如果尚未定义(即第一个文件),则$i设置为1

$i++用作sprintf的参数意味着对于每个处理的文件,$i的值都会增加。

有关完整说明,请参阅our in the perl docs。这里的关键是每个重命名都发生在一个循环中,因此需要our来使定义对整个脚本是全局的,而不是在循环内的本地。这意味着这意味着在循环的迭代之间共享相同的变量,因此计数器不会每次都重置。

答案 1 :(得分:2)

代码显然是在use strict;范围内编译的。除其他外,这会强制执行变量声明。

变量通常使用my声明,使它们成为词汇变量。词法变量只存在于声明变量的花括号的末尾,或者直到替换结束时#34;表达式#34;在这种情况下。

更少见的是,变量是使用our声明的。这使得它们成为包变量。即使退出当前的词汇范围,这些仍然存在。这允许$i在替换表达式的调用之间保持其值。

顺便说一下,

s/.*/our $i; if(!$i) { $i=1; } sprintf("%03d.jpg", $i++)/e

可以缩短为

s/.*/our $i; sprintf("%03d.jpg", ++$i)/e

甚至

s/.*/sprintf("%03d.jpg", ++(our $i))/e

甚至

s/.*/sprintf("%03d.jpg", ++$::i)/e