使用来自 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 语法的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Perl 中输入多行注释? [复制]

使用 Regex / Perl 解析日期列

如何使用 Python 将标准输入/标准输出通过管道传输到 Perl 脚本

重定向与管道

Perl 命令行多行替换

Xargs