perl + awk + запустить awk из системной команды в perl (проблема с синтаксисом?) - PullRequest
0 голосов
/ 20 июля 2010

пишу следующий скрипт

  #!/usr/bin/perl

  system("  awk -F"=" '{s[$1]++}{print $1s[$1],$2}' OFS="=" /var/tmp/file " );

когда я запускаю скрипт, я получаю:

      Can't modify string in scalar assignment at ./stam2 line 5,             near "" /var/tmp/file " )"
       Execution of ./stam2 aborted due to compilation errors.

в чем тут проблема?

Lidia

• цель скрипта - манипулировать и добавлять числа после каждого параметра в строке

Ответы [ 4 ]

1 голос
/ 20 июля 2010

Perl поставляется с программой под названием a2p, которая переводит awk в Perl.Возможно, вы найдете это лучшим решением, чем вызов awk из Perl.

1 голос
/ 20 июля 2010

Вы выполняете оператор, в котором есть знак равенства, как часть системного вызова (), который вы не можете сделать.

Я подозреваю, что это может быть то, что вы хотите:

 #!/usr/bin/perl

  system( qq{  awk -F"=" '{s[$1]++}{print $1s[$1],$2}' OFS="=" /var/tmp/file } );
0 голосов
/ 20 июля 2010

Вы не избегаете или не цитируете свои цитаты.

Литеральная строка " awk -F" начинается с двойной кавычки и продолжается только до тех пор, пока не увидит еще одну неоткрытую двойную кавычку.Так что сделано на F".Если после этого поставить =, то это совершенно другой токен .Вы назначаете.

Причина, по которой в сообщении об ошибке написано, что назначение происходит справа налево.Посмотрите дальше вниз, и вы увидите

"...OFS="=" /var/tmp/file "

Это назначение, с которого оно начинается.Затем он смотрит влево и видит, что вы присваиваете его назначению.И дает вам ошибку, которую вы получаете.

Perl позволит вам поместить двойные кавычки в интерполированную строку (такую, которая допускает «строковое преобразование» переменных), которые обычно обозначаются двойными кавычками.Но вам нужно использовать qq:

Посмотрите внимательно на раскраску между двумя линиями:

system("  awk -F" = " '{s[$1]++}{print $1s[$1],$2}' OFS=" = " /var/tmp/file " );
system( qq(awk -F"=" '{s[$1]++}{print $1s[$1],$2}' OFS="=" /var/tmp/file));

Посмотрите очень внимательно на первую строку, обратите внимание, что остальная часть строкикрасноватый, в то время как равны черный .Он выпрыгнул из строки, и вы имеете дело с = в качестве нового токена.

Теперь, SO подсветка не слишком хорошо справляется со всеми возможностями Perl, поэтому оператор qq( не подсвечен правильно.Но если вы проигнорируете это, вы увидите, что все содержимое в кавычках отображается как в кавычках.И если вы верите, что qq справится с передачей всего этого как строки, то вы поверите, что это все грамматическая единица SAME .

0 голосов
/ 20 июля 2010

Из того, что я понимаю, о системной команде является то, что она берет список строк, где каждая строка - это отдельная команда, которую вы выполняете.У вас уже есть проблемы, потому что операторы не заключены в кавычки.Я бы попробовал это:

system("awk -F\"=\" '{s[$1]++}{print $1s[$1],$2}' OFS=\"=\" /var/tmp/file");

Однако, кажется, что вы действительно хотите сделать, легко можно сделать с помощью разбиения и объединения Perl.Что-то вроде:

open my $fh, '<', "/var/tmp/file" or die "could not open for read.";
open my $output, '>', "/var/tmp/outfile" or die "could not open for write.";
while(<$fh>){
    my $line = $_;
    my @fields = split(/\=/, $line);
    for my $field (@fields){
        $field++;
    }
    print $output join(";", @fields);
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...