Perl скрипт выдает синтаксическую ошибку для команды awk - PullRequest
1 голос
/ 29 марта 2020

У меня есть файл, который содержит ИД пользователя и пароль. Мне нужно получить идентификатор пользователя и пароль из этого файла, передав идентификатор пользователя в качестве элемента поиска с помощью команды awk.

user101,smith,smith@123
user102,jones,passj@007
user103,albert,albpass@01

Я использую команду awk внутри моего perl сценария, например:

...
...
my $userid = ARGV[0];
my $user_report_file = "report_file.txt";
my $data = `awk -F, '$1 ~ /$userid/ {print $2, $3}' $user_report_file`;

my ($user,$pw) = split(" ",$data);
...
...

Здесь я получаю сообщение об ошибке:

awk:  ~ /user101/ {print , }
awk:  ^ syntax error

Но если я запускаю ту же команду в окне терминала, она может дать результат, как показано ниже:

$] awk -F, '$1 ~ /user101/ {print $2, $3}' report_file.txt
smith smith@123

Что может быть вопрос здесь?

1 Ответ

3 голосов
/ 29 марта 2020

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

my $data = `awk -F, '\$1 ~ /$userid/ {print \$2, \$3}' $user_report_file`;

Если вы этого не сделаете, вы ' повторная интерполяция переменных захвата из последнего успешного Perl совпадения.

Когда у меня возникают проблемы такого рода, я сначала пытаюсь ввести команду в виде строки, чтобы увидеть, соответствует ли она ожиданиям:

my $data = "awk -F, '\$1 ~ /$userid/ {print \$2, \$3}' $user_report_file";
say $data;

Вот Perl эквивалент этой команды:

$ perl -aF, -e '$F[0]=~/101/ && print "@F[1,2]"' report_file

Но это то, что вы, вероятно, захотите сделать в Perl вместо создания другого процесса:

  • Интерполяция данных во внешние команды может go неверна, например, имя файла foo.txt; rm -rf /.
  • Запущенный вами awk является первым в пути, поэтому кто-то может сделать это полностью другая программа (поэтому используйте полный путь, например /usr/bin/awk).
  • Проверка заражения может сообщить вам, когда вы передаете неанализованные данные в оболочку.

Внутри программы, которую вы надеваете получить все ярлыки, но если это часть йо Если ваша программа работает медленно, вы, вероятно, захотите переосмыслить доступ к этим данным, поскольку сканирование всего файла любым инструментом не будет таким быстрым:

open my $fh, '<', $user_report_file or die;
while( <$fh> ) {
    chomp;
    my @F = split /,/;
    next unless $F[0] =~ /\Q$userid/;
    print "@F[1,2]";
    last; # if you only want the first one
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...