【问题标题】:Perl script throws syntax error for awk commandPerl 脚本为 awk 命令引发语法错误
【发布时间】:2020-07-09 19:12:12
【问题描述】:

我有一个文件,其中包含每个用户的用户名和密码。我需要通过使用 awk 命令将用户 ID 作为搜索元素传递来从该文件中获取用户 ID 和密码。

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

我在我的 perl 脚本中使用 awk 命令,如下所示:

...
...
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

这可能是什么问题?

【问题讨论】:

  • 为什么要在 perl 中执行 awk 而不是在 perl 中执行?
  • 因为awk 可以执行更快的搜索。
  • $userid$user_report_file 被替换为它们的值,那么 $1 $2$3 不会也被替换吗?对于这些情况,您必须逃避$
  • 你确定脱壳 + 运行 awk 比在 Perl 中运行搜索要快吗?
  • awk 也在做“文件操作”。还有更多,因为 perl 必须在一个变量中捕获它的所有输出......

标签: perl awk


【解决方案1】:

反引号是双引号上下文,因此您需要转义您希望 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 中执行的操作,而不是创建另一个进程:

  • 将数据插入外部命令可能会出错,例如文件名foo.txt; rm -rf /
  • 您运行的 awk 是路径中的第一个,因此有人可以将其设为完全不同的程序(因此请使用完整路径,例如 /usr/bin/awk)。
  • 污点检查可以告诉您何时将未经处理的数据传递给 shell。

在程序中,您不会获得所有快捷方式,但如果这是程序中速度较慢的部分,您可能需要重新考虑如何访问这些数据,因为使用任何工具扫描整个文件都不是会那么快:

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
    }

【讨论】:

  • 谢谢@brian。我正在寻找那个awk 命令。我想我错过了逃跑$
猜你喜欢
  • 2014-05-02
  • 2016-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多