3

我有一个格式为

 location:
 rome

 participants:
 cesar
 pompei
 Sylla

我正在尝试调用perl以获取给定键的值,例如我的带参数函数participants将返回

 cesar
 pompei
 Sylla

我面临的问题是,如果没有该选项-n,我的正则表达式似乎都不起作用。例如我期待

> perl -e '/(.*)/ms && print "$1\n" ' input.txt

打印整个文档。

4

4 回答 4

4

在命令行上,您不妨使用段落模式:

perl -MData::Dumper -00 -anlwe 
    '$h=shift @F; $a{$h}=[@F]; }{ print Dumper \%a;' ceasar.txt

输出:

$VAR1 = {
          'participants:' => [
                               'cesar',
                               'pompei',
                               'Sylla'
                             ],
          'location:' => [
                           'rome'
                         ]
        };

解释:

  • -MData::Dumper使用 Data::Dumper 模块。这仅用于演示,与您的问题无关。
  • -00使用段落模式,这意味着 - 简单地说 - 将输入记录分隔符设置为\n\n,以便输入在双换行符上拆分。
  • -a在空白处拆分段落。您可以使用它来限定它,-F'\n'使其仅在换行符上拆分。
  • -nwhile (<>)程序周围的隐式循环。
  • -l此示例并非严格要求,但它以方便的方式为您处理换行符结尾。
  • @F是自动拆分选项使用的数组。这意味着我们将段落中的第一个单词作为标题,其余单词作为参数。
于 2012-11-13T20:29:27.783 回答
2

默认情况下-n-p一次一行地向您的单行脚本提供输入。因此,要使用多行搜索,您必须告知perl使用不同的记录分隔符。使用该-0选项。

要在一行中读取整个文件:

perl -0777 -ne '...' input.txt

要使用“段落模式”(拆分为两个或多个连续的换行符,这可能是您想要解决此问题的方式):

perl -00 -ne '...' input.txt
于 2012-11-13T19:07:21.107 回答
1

如果你不使用 -n 你必须明确地阅读输入,例如

while(<>){do...}

您没有得到匹配,因为您实际上并没有从标准输入读取任何内容。

于 2012-11-13T18:37:35.670 回答
1

测试了这个:

# cat file
location:
rome

participants:
cesar
pompei
Sylla

现在得到participants

# perl -e 'undef $/; $_=<>; /participants:\s*(.*?)(\n\n|$)/s && print "$1\n";' file
cesar
pompei
Sylla

UPD:正如 TLP 所提到的,它可以用 -0 开关重写:

# perl -0777 -e '$_=<>; /participants:\s*(.*?)(\n\n|$)/s && print "$1\n";' file
cesar
pompei
Sylla
于 2012-11-13T19:07:01.523 回答