Страница 1 из 1
Perl command-line quirks
Добавлено: 29 янв 2008, 00:25
mrskhris
Товарищи программисты и сочуствующие, не сталкивался ли кто из вас со следующей проблемой:
Имеем некий набор файлов, в котором нужно сделать массовую замену. Имеется привычный метод, как-то:
perl -p -i.old -e 's#foo#bar#' *.txt
(это общий пример, конечно).
Хочется: странного, а именно - чтобы при работе скрипта в командной строке выводилось имя файла, который обрабатывается в данный момент.
Теоретически (не факт что так, но теоретически), скрипт (тот, что в -e), использует while (<>) как источник данных. Вот это <> - это STDIN? А можно ли как-нибудь узнать, какой именно файл сейчас открыт на чтение?
Я понимаю, что все это сделать можно и совсем по-другому. меня интересует именно вариант с -p -e, если он вообще возможен.
Re: Perl command-line quirks
Добавлено: 29 янв 2008, 00:39
папа Карло
Код: Выделить всё
use strict;
my @files = <*.tmp>;
foreach my $file (@files)
{
print "$file\n";
# do something....
}
что-то типа такого?
Re: Perl command-line quirks
Добавлено: 29 янв 2008, 00:40
CdR
Собственно название файла в $ARGV[0].
Как его использовать -- дело вкуса.
типа такого ?
perl -i.old -p -e 's/foo/bar/ ; print STDERR "$ARGV[0]\r"' *.txt
Re: Perl command-line quirks
Добавлено: 29 янв 2008, 00:48
mrskhris
папа Карло писал(а):что-то типа такого?
Эмммм... ну типа, но дело не просто в создании списка файлов

Я могу задачу полнее объяснить, но я боюсь, что еще больше все запутаю.
Re: Perl command-line quirks
Добавлено: 29 янв 2008, 00:50
mrskhris
CdR писал(а):Собственно название файла в $ARGV[0].
Очевидно, мне надо больше спать. Балда я балда - про $ARGV[0] забыла.
Спасибо. Да, я его через STDERR и сбрасывала куда нужно.
Re: Perl command-line quirks
Добавлено: 29 янв 2008, 01:13
mrskhris
CdR писал(а):perl -i.old -p -e 's/foo/bar/ ; print STDERR "$ARGV[0]\r"' *.txt
Идея, вроде, хорошая. Но работает несколько странно.
Пример (упрощенный):
Три файла:
t1.txt, t2.txt, t3.txt
t1.txt: fooText1bar
t2.txt: fooText2bar
t3.txt: fooText3bar
Запускаем следующую команду:
perl -p -i.old -e 's#foo(.*)bar#$1#; print STDERR "$ARGV[0] contains $1\n"' *.txt 2>>log.dat
Результат - log.dat содержит
t2.txt contains Text1
t3.txt contains Text2
contains Text3
По какой-то странной причине, $ARGV[0] съезжает на шаг вперед. Попробовала под cygwin и под RH - результат один и тот же. Похоже, я впадаю в маразм. Что тут происходит, объясните, а?
Re: Perl command-line quirks
Добавлено: 29 янв 2008, 08:10
CdR
mrskhris писал(а):Похоже, я впадаю в маразм. Что тут происходит, объясните, а?
ага. +1

Re: Perl command-line quirks
Добавлено: 29 янв 2008, 09:46
mrskhris
Так. Умные люди объяснили.
-p causes Perl to assume the following loop around your program,
which makes it iterate over filename arguments somewhat like sed:
LINE:
while (<>) {
... # your program goes here
} continue {
print or die "-p destination: $!\n";
}
Это просто кусок из мана.
А в момент использования while происходит shift на @ARGV. @ARGV при этом содержит не одно имя файла само по себе, а весь список разименованный из маски. Поэтому там и оказывается следующее по списку значение.
(примечание - сдвигаются значения (поочередно) в переменную $ARGV)
Re: Perl command-line quirks
Добавлено: 29 янв 2008, 10:03
CdR
mrskhris писал(а):Три файла: t1.txt, t2.txt, t3.txt
t1.txt: fooText1bar
t2.txt: fooText2bar
t3.txt: fooText3bar
Запускаем следующую команду:
perl -p -i.old -e 's#foo(.*)bar#$1#; print STDERR "$ARGV[0] contains $1\n"' *.txt 2>>log.dat
Результат - log.dat содержит
t2.txt contains Text1
t3.txt contains Text2
contains Text3
BTW:
perl -p -i.old -e 'm#foo(.*)bar#; print STDERR "
$ARGV contains $1\n"' *.txt
получаем:
t1.txt contains Text1
t2.txt contains Text2
t3.txt contains Text3
Так что не всё потеряно.
Re: Perl command-line quirks
Добавлено: 29 янв 2008, 10:29
mrskhris

спасибо, но как раз об этом предыдущий пост и есть.
Re: Perl command-line quirks
Добавлено: 29 янв 2008, 10:37
CdR
mrskhris писал(а):
спасибо, но как раз об этом предыдущий пост и есть.
О, блин. последнюю строку недочитал.