【问题标题】:heredoc syntax for multi-line perl using stdin from bash使用来自 bash 的标准输入的多行 perl 的 heredoc 语法
【发布时间】: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

标签: perl bash stdin heredoc


【解决方案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

【讨论】:

    猜你喜欢
    • 2012-01-28
    • 2016-10-28
    • 2019-06-27
    • 2018-10-18
    • 2021-11-10
    • 2011-02-06
    • 1970-01-01
    • 2013-07-19
    • 2018-11-28
    相关资源
    最近更新 更多