如何在 Perl 中 grep 后提取匹配大括号之间的字符串?

问题描述 投票:0回答:2

我有一个以下文本格式的文件: 猫测试.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:如何提取括号之间的字符串但此链接仅提取两个括号之间的单词,我需要提取行。

任何有效的方法都会被接受,但解释会有很大帮助。

regex string bash perl pattern-matching
2个回答
0
投票

你可以进行括号捕获,但当你不需要时,它会很混乱。 (

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 数据结构,您可以根据需要遍历它。


0
投票

反向引用很混乱? 从什么时候开始? 我不同意它对我来说看起来并不混乱。 事实上,我认为这是正确的做法。 此外,您不需要从 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
© www.soinside.com 2019 - 2024. All rights reserved.