perl - Perl 中的 eval gawk,如何处理引号?
问题描述
我有一个看起来像这样的文件:
NameA X Y 0 Add1
NameA X Y 1 Add1
NameB X Y 1 Add1
NameB X Y 0 No
NameB X Y 1 No
我正在通过 gawk 运行它,如下所示:
gawk -v OFS='\t' workdir=$workdir '{FS = OFS} {if ($0 ~ /Add1/) {print $2, $3, $4 + 1, $5"_done" >> workdir"/"$1; close($1)} else {print $2, $3, $4, $5"_done" >> workdir"/"$1; close($1)}}' input_file.txt
预期的输出是:
workdir/NameA:
NameA X Y 1 Add1
NameA X Y 2 Add1
workdir/NameB:
NameB X Y 2 Add1
NameB X Y 0 No
NameB X Y 1 No
效果很好,
我现在想使用 perl 将其合并到工作流中,并将其写在此块中:
else {
my $gawk = "gawk -v OFS='\t' workdir=$workdir '{FS = OFS} {if ($0 ~ /Add1/) {print $2, $3, $4 + 1, $5"_done" >> workdir"/"$1; close($1)} else {print $2, $3, $4, $5"_done" >> workdir"/"$1; close($1)}}' $input";
eval {
`$gawk`;
};
where$workdir
和$input
前面已经定义了。
我遇到了这个错误:
String found where operator expected at xxxxx.pl line 511 near $5"_done""
我想我在某处搞砸了引号,但任何输入都会有所帮助!
解决方案
问题 #1:您没有正确构造字符串文字。具体来说,当您希望它生成包含这些字符的字符串时\
,需要在双引号字符串文字中对其进行转义。$
"
问题 #2:您没有正确构建您的 shell 命令。具体来说,您没有正确地将$workdir
and的值转换$input
为 shell 字符串文字。这是危险的。
-v
问题 #3:您在尝试设置时缺少 a $workdir
。
使固定:
use String::ShellQuote qw( shell_quote );
my $gawk_prog = <<'__END_OF_CMD__';
...Put nicely formatted gawk code here...
__END_OF_CMD__
my $shell_cmd = shell_quote(
"gawk",
-v => "OFS=\\t",
-v => "workdir=$workdir",
$gawk_prog,
$input,
);
my $output = `$shell_cmd`;
die("gawk killed by signal ".( $? & 0x7F )."\n") if $? & 0x7F;
die("gawk exited with error ".( $? >> 8 )."\n") if $? >> 8;
注意:您可以BEGIN { OFS = "\t" }
在程序中使用而不是使用-v
来设置OFS
为常数值。
注意:使用没有意义,eval
因为readpipe
(反引号)不会引发异常。
注意:在单引号 heredocs 中,\
除了终止标记之外,没有什么特别的——甚至反斜杠 ( ) 也没有。这使得生成由代码组成的字符串非常方便。
注意:您要求gawk
做的事情可以在 Perl 中轻松完成。
推荐阅读
- html - 如何从 Rails 中的 API 调用结果中选择数据?
- sql-server - SQL Server:按分组列求和并按另一列排序
- r - “证书链是由不受信任的机构颁发的” - 使用 RVest 时出错
- javascript - 无限平铺网页
- r - 当矩阵包含许多小条目时,base::chol() 会变慢
- python - Tkinter 部分点击通过?(仅限 Windows)
- css - 悬停时两个不同元素的转换延迟反转
- python - 将千位逗号分隔符添加到 Relplot
- python - 使用 Python 中的带阻滤波器滤除频率范围,并使用傅里叶变换 FFT 确认
- android - 无法使用 Fastlane 上传 aab/apk 来玩商店