переменная для разделителя полей в Perl - PullRequest
9 голосов
/ 24 июня 2011

В awk я могу написать: awk -F: 'BEGIN {OFS = FS} ...'

В Perl, что эквивалентно FS?Я хотел бы написать

perl -F: -lane 'BEGIN {$, = [what?]} ...'

обновление с примером:

echo a:b:c:d | awk -F: 'BEGIN {OFS = FS} {$2 = 42; print}'
echo a:b:c:d | perl -F: -ane 'BEGIN {$, = ":"} $F[1] = 42; print @F'

Оба вывода a:42:c:d

Я бы предпочел незакодируйте : в блоке Perl BEGIN, но обращайтесь к тому, где опция -F сохраняет свой аргумент.

Ответы [ 5 ]

6 голосов
/ 24 июня 2011

Подводя итог, то, что я ищу, не существует:

  1. нет переменной, содержащей аргумент для -F, и что более важно
  2. "FS" в Perl принципиально отличается от типа данных (регулярное выражение) от OFS (строка) - нет смысла объединять список строк с помощью регулярного выражения.

Обратите внимание, что то же самое верно в awk: FS является строкой, но действует как регулярное выражение:

echo a:b,c:d | awk -F'[:,]' 'BEGIN {OFS=FS} {$2=42; print}'

выводит "a[:,]42[:,]c[:,]d"

Спасибо за понимание и обходные пути.

2 голосов
/ 24 июня 2011

Если вы знаете точную длину ввода, вы можете сделать это:

echo a:b:c:d | perl -F'(:)' -ane '$, = $F[1]; @F = @F[0,2,4,6]; $F[1] = 42; print @F'

Если ввод переменной длины, вам понадобится что-то более сложное, чем @f [0,2,4,6].

EDIT: -F, по-видимому, просто обеспечивает ввод для автоматического вызова split (), который принимает полный RE в качестве выражения. Вы можете найти что-то более подходящее, прочитав записи perldoc для split , perlre и perlvar .

1 голос
/ 25 июня 2011

Вы можете сортировать обмануть его, потому что perl фактически использует функцию split с вашим аргументом -F, и вы можете сказать split, чтобы сохранить то, на что он делится, включая захват паренов в регулярном выражении:

$ echo a:b:c:d | perl -F'(:)' -ane 'print join("/", @F);'
a/:/b/:/c/:/d

Вы можете увидеть, что Perl делает с некоторыми из этих «волшебных» аргументов командной строки, используя -MO=Deparse, например:

$ perl -MO=Deparse -F'(:)' -ane 'print join("/", @F);'
LINE: while (defined($_ = <ARGV>)) {
    our(@F) = split(/(:)/, $_, 0);
    print join('/', @F);
}
-e syntax OK

Вам придется изменить подписчиков @F, чтобы они удвоились по сравнению с обычными значениями ($F[2] = 42).

1 голос
/ 25 июня 2011

Дарнит ...

Лучшее, что я могу сделать, это:

echo a:b:c:d | perl -ne '$v=":";@F = split("$v"); $F[1] = 42; print join("$v", @F) . "\n";'

Вам не нужно -F: таким образом, и вы только один раз указываете двоеточие,Я надеялся, что каким-то образом можно было установить переменные в командной строке, как вы можете с помощью переключателя Awk -v.

Для одних строк Perl обычно не так чист, как Awk, но я помню, как использовал Awk, прежде чем я зналPerl и написание 1000+ строковых скриптов Awk.

Испытывая подобные вещи, люди думали, что Awk или назвали в честь звука, который кто-то издал, когда они пытались расшифровать такой сценарий, или стояли за AWKward.

0 голосов
/ 24 июня 2011

В Perl нет разделителя входных записей. Вы в основном эмулируете awk, используя флаги -a и -F. Если вы действительно не хотите жестко кодировать значение, то почему бы просто не использовать переменную окружения?

$ export SPLIT=":"
$ perl -F$SPLIT -lane 'BEGIN { $, = $ENV{SPLIT}; } ...'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...