【问题标题】:Perl script versus one-liner - differences in functionality with regexPerl 脚本与单行 - 正则表达式的功能差异
【发布时间】:2026-01-15 20:25:02
【问题描述】:

我有一个使用 STDIN 的 perl 程序(从另一个 bash 命令通过管道传输)。 bash 命令的输出非常大,大约 200 行。我想获取 整个 输入(多行)并将其提供给单行 perl 脚本,但到目前为止我没有尝试过任何工作。相反,如果我使用以下 perl(.pl 文件):

#!/usr/bin/perl
use strict;

my $regex = qr/{(?:\n|.)*}(?:\n)/p;

if ( <> =~ /$regex/g ) {
  print "${^MATCH}\n";
}

然后像这样执行我的 bash 命令:

<bash command> | perl -0777 try_m_1.pl

它有效。但作为单行,它不适用于相同的 regex/bash 命令。 print 命令的结果是什么。我试过这样:

<bash command> | perl -0777 -e '/{(?:\n|.)*}(?:\n)/pg && print "$^MATCH";'

还有这个:

<bash command> | perl -0777 -e '/{(?:\n|.)*}(?:\n)/g; print "$1\n";'

还有很多其他的东西,太多了,无法一一列举。我是 perl 新手,只想用它从文本中获取正则表达式输出。如果有比 perl 更好的方法(我从阅读中了解到 sed 对此不起作用?)随时提出建议。

更新:根据@zdim 的回答,我尝试了以下方法,效果很好:

<bash command> |  perl -0777 -ne '/(\{(?:\n|.)*\}(?:\n))/s and print "$1\n"'

我想我的正则表达式需要用() 包裹,{ 大括号需要转义。

【问题讨论】:

  • ${^MATCH} vs $^MATCH 可能是个问题。而且您永远不会为$1 捕获任何有价值的东西...另外,您的一个班轮需要-n...

标签: regex bash perl


【解决方案1】:

单线需要-n(或-p)来处理输入,以便打开文件、附加流并设置循环。即使-0777 取消设置input record separator,它仍然需要它,因此文件被立即读取;见Why use the -p|-n in slurp mode in perl one liner?

该正则表达式匹配换行符或换行符以外的任何字符,并且有一个修饰符/s. 也匹配换行符。然后需要在花括号内,您需要在较新的 Perls 中对其进行转义。后面的换行不需要分组。

所以你应该有

<bash command> | perl -0777 -ne'/(\{(.*)\}\n)/s and print "$1\n"'

【讨论】:

  • 正则表达式和语法不太正确(例如,/s 后面有一个单引号字符 ' 不应该存在,但根据您的建议 @zdim,我尝试了 ` perl - 0777 -ne '/(\{(?:\n|.)*\}(?:\n))/s 并打印 "$1\n"'` 并且有效。谢谢。
  • @Nena 太好了,很高兴它成功了,感谢您的贡献。感谢您通知错字!固定
  • 感谢您在这里的解释。这比我关闭的问题中的副本要好。 :)
  • @LeoNatan 太好了,谢谢你这么说:)。这里有一些相关的帖子供参考,short oneone with more 的东西。