2015-11-24 66 views
1

任何人都可以解釋發生的our命令行中的Perl表達式 - 重命名文件

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

該代碼顯然編譯在use strict;的範圍內。除其他外,這強制了變量的聲明。

變量通常使用my聲明,使它們成爲詞彙變量。詞法變量只存在於聲明變量的花括號的末尾,或者直到本例中替換「表達式」的結尾。

更爲罕見的是,使用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 
2

它看起來像它讓你重新使用全局變量$i在當前重命名操作的範圍內。

如果它尚未定義(即第一個文件),$i設置爲1

用作參數sprintf的參數$i++表示對於每個處理的文件,$i的值增加。

有關完整說明,請參閱our in the perl docs。這裏的關鍵是每個重命名都在一個循環中發生,因此需要our將定義全局化爲整個腳本,而不是循環內的本地。這意味着這意味着同一個變量在迭代循環之間共享,所以計數器不會每次都被重置。

相關問題