2015-11-24 3 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.

$i++, используемый в качестве аргумента для sprintf, означает, что для каждого обрабатываемого файла увеличивается значение $i.

См. our in the perl docs для получения полного описания. Ключевым моментом здесь является то, что каждое переименование происходит в цикле, поэтому our необходим, чтобы сделать определение глобальным по всему сценарию, а не локально внутри цикла. Это означает, что одна и та же переменная распределяется между итерацией цикла, поэтому счетчик не сбрасывается каждый раз.

Смежные вопросы