eval gawk在Perl中,如何处理引用?
我有一个文件如下所示:eval gawk在Perl中,如何处理引用?,perl,awk,Perl,Awk,我有一个文件如下所示: 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 {
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`;
};
其中前面定义了$workdir
和$input
我遇到了以下错误:
在$5“\u done”附近的xxxxx.pl行511处找到运算符期望的字符串。
我想我在什么地方弄乱了引号,但是任何输入都会有帮助!问题1:您没有正确地构造字符串文字。具体地说,\
、$
和“
当您希望生成包含这些字符的字符串时,需要以双引号字符串文字对其进行转义
问题2:您没有正确构造shell命令。具体来说,您没有正确地将$workdir
和$input
的值转换为shell字符串文本。这是
问题3:尝试设置$workdir
时缺少-v
修正:
使用字符串::ShellQuote qw(shell_quote);
我的$gawk_prog=“workdir=$workdir”,
$gawk_prog,
$input,
);
my$output=`$shell\u cmd`;
如果$?&0x7F,则为“死亡”($?&0x7F)。“\n”)如果$?&0x7F;
如果$?>>8.
注意:您可以在使用-v
的程序界面中使用BEGIN{OFS=“\t”}
将OFS
设置为常量值
注意:使用eval
没有意义,因为readpipe
(backticks)不会引发异常
注意:在单引号的heredocs中,除了终止标记之外,没有什么特别的东西-甚至连反斜杠(\
)都没有。这使得生成由代码组成的字符串非常方便
注意:您要求的gawk
也可以用Perl轻松完成。问题1:您没有正确构造字符串文字。具体来说,\
、$
和“
需要以双引号字符串文本进行转义,以便生成包含这些字符的字符串
问题#2:您没有正确构造shell命令。具体而言,您没有正确地将$workdir
和$input
的值转换为shell字符串文本。这是错误的
问题3:尝试设置$workdir
时缺少-v
修正:
使用字符串::ShellQuote qw(shell_quote);
我的$gawk_prog=“workdir=$workdir”,
$gawk_prog,
$input,
);
my$output=`$shell\u cmd`;
如果$?&0x7F,则为死($?&0x7F)。“\n”)如果$?&0x7F;
如果$?>>8,则为“死亡”($?>>8)。”\n“;
注意:您可以在使用-v
的程序界面中使用BEGIN{OFS=“\t”}
将OFS
设置为常量值
注意:使用eval
没有意义,因为readpipe
(backticks)不会引发异常
注意:在单引号的heredocs中,除了终止标记之外,没有什么特别的东西-甚至反斜杠(\
)-这使得生成由代码组成的字符串非常方便
注意:您要求的
gawk
也可以用Perl轻松完成。行中有额外的双引号--$5“
之后,开始引号关闭,其余的是语法错误。不过,还有很多可能需要引号。。。一个好的工具是String::ShellQuote
(对于bash
,如果通过bash
),但是您可能需要在这里做更多的工作,重写该命令,以便正确引用内容。有一件事很有帮助,那就是使用q()
(运算符形式的单引号),这样Perl就可以原封不动地传递内部内容,而无需插值从Perl调用awk不是正确的方法,因为Perl可以做awk可以做的任何事情。我绝对支持@EdMorton的评论(我上面的评论认为,出于某种原因,你必须保留你的awk
代码……但这可能是不正确的)嗯,行中有额外的双引号-$5之后“
开头的引号已关闭,其余的是语法错误。但是,可能有很多地方需要引用…一个好的工具是String::ShellQuote
(对于bash
,如果通过bash
)但您可能需要在这里做更多的工作,重写该命令,以便正确引用内容。有一件事很有帮助,就是使用q()
(运算符形式的单引号)因此,Perl在不插入的情况下传递内部内容,从Perl调用awk不是正确的方法,因为Perl可以做awk可以做的任何事情。我绝对支持@EdMorton的评论(我上面的评论认为出于某种原因,您必须保留awk
代码……但这可能是不正确的)
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;