使用来自 bash 的标准输入的多行 perl 的 heredoc 语法
Posted
技术标签:
【中文标题】使用来自 bash 的标准输入的多行 perl 的 heredoc 语法【英文标题】:heredoc syntax for multi-line perl using stdin from bash 【发布时间】:2013-04-16 01:03:26 【问题描述】:如何将文件传递给 perl 脚本进行处理,并为多行 perl 脚本使用 heredoc 语法?我试过了,但没有运气:
cat ng.input | perl -nae <<EOF
if (@F==2) print $F[0] . "\t". $F[1] . "\n" else print "\t" . $F[0] . "\n"
EOF
cat ng.input | perl -nae - <<EOF
if (@F==2) print $F[0] . "\t". $F[1] . "\n" else print "\t" . $F[0] . "\n"
EOF
【问题讨论】:
所有你需要的是perl -ple'$_="\t$_"if!/\t/'
(如果@F!=2 当@F
【参考方案1】:
使用进程替换:
cat ng.input | perl -na <(cat <<'EOF'
if (@F==2) print $F[0] . "\t". $F[1] . "\n" else print "\t" . $F[0] . "\n"
EOF
)
还要在EOF
标记周围加上单引号,这样perl 脚本中的$F
就不会被扩展为shell 变量。
【讨论】:
@JonathanLeffler 谢谢,我什至没有注意到原始问题中的-e
。【参考方案2】:
真的不需要here-docs。您可以简单地使用多行参数:
perl -nae'
if (@F==2)
print $F[0] . "\t". $F[1] . "\n"
else
print "\t" . $F[0] . "\n"
' ng.input
干净,比 Barmar 的更便携,并且只使用一个进程而不是 Barmar 的三个。
请注意,您的代码可能会缩小为
perl -lane'unshift @F, "" if @F!=2; print "$F[0]\t$F[1]";' ng.input
甚至
perl -pale'unshift @F, "" if @F!=2; $_="$F[0]\t$F[1]";' ng.input
【讨论】:
我认为问题中的cat ng.input
只是将输入到脚本的其他一些进程的占位符。否则使用 here-doc 不会有问题。
@Barmar,这完全不是重点。多行参数也可以与... | perl
一起使用。 (但无论如何要解决您的评论,您低估了有多少人使用cat file |
。)
这就是为什么有 UUOC 奖的原因,虽然实际上很难找到一个新颖的 UUOC - 它们主要是对同一个老问题的平凡重复,一遍又一遍。【参考方案3】:
也可以将heredoc作为“-”第一个参数传递给perl:
perl -lna - ng.input <<'EOF'
if (@F==2) print $F[0] . "\t". $F[1] . "\n" else print "\t" . $F[0] . "\n"
EOF
【讨论】:
以上是关于使用来自 bash 的标准输入的多行 perl 的 heredoc 语法的主要内容,如果未能解决你的问题,请参考以下文章