我有一个以下文本格式的文件: 猫测试.txt
"perl-Test::DNS" : [
{
"environment" : "test1",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test1-Test::DNS",
},
{
"environment" : "Test2",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test2-Test::DNS",
},
{
"environment" : "Test3",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test3-Test::DNS",
},
]
"perl-Test::SSH" : [
{
"environment" : "test1",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test1-Test::SSH",
},
{
"environment" : "Test2",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test2-Test::SSH",
},
{
"environment" : "Test3",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test3-Test::SSH",
},
],
我需要从文件中 grep 特定字符串,即“perl-Test::SSH : [”,并打印/提取该字符串的“[”和“]”之间的整行。
我在这里发现了类似类型的问题:Perl:如何提取括号之间的字符串但此链接仅提取两个括号之间的单词,我需要提取行。
任何有效的方法都会被接受,但解释会有很大帮助。
你可以进行括号捕获,但当你不需要时,它会很混乱。 (
JSON
比XML
更容易处理,但仍然不是一个好主意)。
然而,这看起来可能是
YAML
- 它非常接近 - 我只需要从你的源代码中删除尾随的逗号,我认为这是因为你给了我们你的配置样本。
加载 YAML 看起来有点像这样:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
use YAML::XS;
my $yaml = Load ( do { local $/; <DATA> } );
print Dumper $yaml -> {"perl-Test::DNS"};
__DATA__
"perl-Test::DNS" : [
{
"environment" : "test1",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test1-Test::DNS",
},
{
"environment" : "Test2",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test2-Test::DNS",
},
{
"environment" : "Test3",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test3-Test::DNS",
},
]
"perl-Test::SSH" : [
{
"environment" : "test1",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test1-Test::SSH",
},
{
"environment" : "Test2",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test2-Test::SSH",
},
{
"environment" : "Test3",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test3-Test::SSH",
},
]
如您所见 - 除了尾随逗号之外,它会正确解析您的文件。 (如果您在其后有其他条目,这也可以工作)。以上输出:
$VAR1 = [
{
'environment' => 'test1',
'hash' => 'c8d149b4fc895b214276ca5c90d1181e',
'identifier' => 'test1-Test::DNS'
},
{
'hash' => 'c8d149b4fc895b214276ca5c90d1181e',
'environment' => 'Test2',
'identifier' => 'test2-Test::DNS'
},
{
'hash' => 'c8d149b4fc895b214276ca5c90d1181e',
'environment' => 'Test3',
'identifier' => 'test3-Test::DNS'
}
];
但是这是一个“正常”的 Perl 数据结构,您可以根据需要遍历它。
反向引用很混乱? 从什么时候开始? 我不同意它对我来说看起来并不混乱。 事实上,我认为这是正确的做法。 此外,您不需要从 CPAN 下载或包含任何内容,或将输入文件转换为 YAML 文件。 基本上寻找
"perl-Test::SSH" : [
并匹配所有内容,直到达到结束 ]
解决办法在这里
#!/usr/bin/perl -w
undef $/; #grab entire file at once because there are newlines
while(<>){
if( /\"perl-Test::SSH\" : (\[[\w\W]*?\])/ ){ #non greedy match so it wont miss the closing bracket
print "$1\n";
}
}
输出看起来像这样
$ perl matchInBrackets.pl matchInBrackets.txt
[
{
"environment" : "test1",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test1-Test::SSH",
},
{
"environment" : "Test2",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test2-Test::SSH",
},
{
"environment" : "Test3",
"hash" : "c8d149b4fc895b214276ca5c90d1181e",
"identifier" : "test3-Test::SSH",
},
]
打了 50 个角色的高尔夫球
perl -0777 -ne 'print $1 if(/\"perl-Test::SSH\" : (\[[\w\W]*?\])/);' matchInBrackets.txt