Редактирование «на месте» в командной строке

Программу, приведенную в предыдущем разделе, написать несложно. Но Ларри решил, что и этого недостаточно. Представьте, что вам потребовалось обновить сотни файлов, в которых имя Randal ошибочно записано с двумя l (Randall). Конечно, можно написать программу наподобие приведенной в предыдущем разделе. А можно ввести короткую программу прямо в командной строке:

$ perl -p -i.bak -w -e 's/Randall/Randal/g' fred*.dat

Perl поддерживает многочисленные ключи командной строки, позволяющие строить сложные программы при минимальном объеме кода. Посмотрим, что происходит в этом примере. Начало команды, perl, делает примерно то же, что строка #!/usr/bin/ perl в начале файла: оно указывает, что программа perl должна обработать последующие данные. Ключ –p приказывает Perl автоматически сгенерировать программу. Впрочем, программа получается совсем маленькая; она выглядит примерно так:

while (<>) {
print;
}

Если вам и этого слишком много, используйте ключ –n; с ним команда print не генерируется, так что вы можете вывести только то, что нужно. (Ключи –p и –n знакомы поклонникам awk.) Программа, конечно, минимальная, но для нескольких нажатий клавиш неплохо.


Как нетрудно догадаться, следующий ключ –i.bak задает $^I значение ".bak" перед запуском программы. Если резервная копия не нужна, укажите ключ –i без расширения. (Если запасной парашют не нужен, прыгайте только с основным… может, и не понадобится.) Ключ –w нам уже знаком – он включает предупреждения. Ключ –e означает: «далее следует исполняемый код». Другими словами, строка s/Randall/Randal/g должна интерпретироваться как код Perl.

Так как программа уже содержит цикл while (от ключа –p), код включается в цикл перед командой print. По техническим причинам последняя точка с запятой в коде –e не является обязательной. Но если команда содержит несколько ключей –e (а следовательно, несколько фрагментов кода), без риска можно опустить только точку с запятой в конце последнего фрагмента. Последний параметр командной строки fred*.dat говорит, что массив @ARGV должен содержать список имен файлов, соответствующих этому шаблону. Сложим все вместе: командная строка работает так, как если бы мы написали следующую программу и запустили ее для файлов fred*.dat:

#!/usr/bin/perl -w
$^I = ".bak";
while (<>) {
s/Randall/Randal/g;
print;
}

Сравните эту программу с приведенной в предыдущем разделе. Эти две программы очень похожи. Ключи командной строки удобны, не правда ли?

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Perl на эту тему:
m// в списочном контексте
Глобальная замена (/g)
Другие возможности регулярных выражений
Другие ограничители
Замена с использованием оператора s///