Страница 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 писал(а)::) спасибо, но как раз об этом предыдущий пост и есть.
О, блин. последнюю строку недочитал.