Вы должны изучить свой однострочник, чтобы увидеть, как он работает.Сначала проверьте perl -h
, чтобы узнать об используемых переключателях:
-l[octal] enable line ending processing, specifies line terminator
-n assume "while (<>) { ... }" loop around program
Первый не совсем понятен, но на самом деле -l
означает chomp
каждую строку, а затем измените $\
и $/
до новой строки.Итак, ваш однострочный:
perl -nle 'print /(\d{8}_\d{9})/'
На самом деле это делает:
$\ = "\n";
while (<>) {
chomp;
print /(\d{8}_\d{9})/;
}
Очень простой способ убедиться в этом - использовать команду Deparse:
$ perl -MO=Deparse -nle 'print /(\d{8}_\d{9})/'
BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = <ARGV>)) {
chomp $_;
print /(\d{8}_\d{9})/;
}
-e syntax OK
Итак, вот как вы преобразуете это в рабочий скрипт.
Понятия не имею, как вы перешли от этого к следующему:
use strict;
my $switch="12012011_000005777";
open (FILE, "more /home/shortcasper/work/tagcommands|");
my @array_old = (<FILE>) ;
my @array_new = @array_old ;
foreach my $line(@array_new) {
$line =~ s/\d{8}_\d{9}/$switch/g;
print $line;
sleep 1;
}
Прежде всего, почему вы открываететруба из команды more
для чтения текстового файла?Это все равно что вызывать эвакуатор за такси.Просто откройте файл.Или еще лучше, не надо.Просто используйте оператор diamond, как вы делали это в первый раз.
Вам не нужно сначала копировать строки файла в массив, а затем использовать массив.while(<FILE>)
- это простой способ сделать это.
В одной строке вы печатаете регулярное выражение.Ну, вы печатаете возвращаемое значение регулярного выражения.В этом сценарии вы печатаете $line
.Я не уверен, как ты думал, что это сделает то же самое.
Ваше регулярное выражение здесь удалит весь набор чисел и заменит его на те, что указаны в вашем скрипте.Ничего другого.
Вы также можете знать, что sleep 1
не будет делать то, что вы думаете.Попробуйте этот однострочный, например:
perl -we 'for (1 .. 10) { print "line $_\n"; sleep 1; }'
Как вы заметите, он просто подождет 10 секунд, а затем напечатает все сразу.Это связано с тем, что по умолчанию perl печатает в стандартный выходной буфер (в оболочке!), И этот буфер не печатается до тех пор, пока не будет заполнен или сброшен (после завершения выполнения perl).Итак, это проблема восприятия.Все работает так, как должно, вы просто этого не видите.
Если вы абсолютно хотите, чтобы в вашем скрипте содержалось утверждение сна, вы, вероятно, захотите autoflush , например STDOUT->autoflush(1);
Однако, почему вы это делаете?Так у вас будет время прочитать цифры?Если это так, поместите этот оператор more
в end вашего однострочного текста вместо:
perl ...... | more
, который перенаправит вывод в команду more
, так что вы можете прочитатьэто в вашем собственном темпе.Теперь для вашего однострочного текста:
Всегда также используйте -w
, если только вы не хотите специально избегать получения предупреждений (чего, в принципе, никогда не следует).
Ваш однострочник будет печатать толькопервый матчЕсли вы хотите напечатать все совпадения в новой строке:
perl -wnle 'print for /(\d{8}_\d{9})/g'
Если вы хотите напечатать все совпадения, но оставьте те из одной строки в одной строке:
perl -wnle 'print "@a" if @a = /(\d{8}_\d{9})/g'
Ну, это должно покрыть это.