我有一个格式为
location:
rome
participants:
cesar
pompei
Sylla
我正在尝试调用perl
以获取给定键的值,例如我的带参数函数participants
将返回
cesar
pompei
Sylla
我面临的问题是,如果没有该选项-n
,我的正则表达式似乎都不起作用。例如我期待
> perl -e '/(.*)/ms && print "$1\n" ' input.txt
打印整个文档。
在命令行上,您不妨使用段落模式:
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'
使其仅在换行符上拆分。-n
while (<>)
程序周围的隐式循环。-l
此示例并非严格要求,但它以方便的方式为您处理换行符结尾。@F
是自动拆分选项使用的数组。这意味着我们将段落中的第一个单词作为标题,其余单词作为参数。默认情况下-n
,-p
一次一行地向您的单行脚本提供输入。因此,要使用多行搜索,您必须告知perl
使用不同的记录分隔符。使用该-0
选项。
要在一行中读取整个文件:
perl -0777 -ne '...' input.txt
要使用“段落模式”(拆分为两个或多个连续的换行符,这可能是您想要解决此问题的方式):
perl -00 -ne '...' input.txt
如果你不使用 -n 你必须明确地阅读输入,例如
while(<>){do...}
您没有得到匹配,因为您实际上并没有从标准输入读取任何内容。
测试了这个:
# 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