我有一个项目列表,我想从中选择活动项目的名称:
item {
status: "Active"
properties {
key_a: value
}
id: 42
name: "Foo"
}
item {
status: "Disabled"
properties {
key_b: value
}
id: 12
name: "Bar"
}
item {
status: "Active"
id: 2
name: "Baz"
}
我知道我可以使用捕获组提取名称pcregrep
:
$ cat list.txt | pcregrep -o1 -i '^ name: "(.*)"'
Foo
Bar
Baz
使用 OR 表达式,我还可以获得重复状态值和名称的列表:
$ cat list.txt | pcregrep -o2 -i '^ (status|name): "(.*)"'
Active
Foo
Disabled
Bar
Active
Baz
最后,我需要根据前面的行过滤列表中的名称。我怎样才能做到这一点?
最终输出应该是:
Foo
Baz
我不认为你可以
grep
单独使用变体来做到这一点(诚然我不知道pcregrep
)。尝试awk
:你也可以使用 sed
由于大部分繁重的工作已经由 完成
pcregrep
,您现在可以将其 so/p 传递给这个简短的sed
片段:这使得
sed
一次查看 2 行,而不是默认的 1 行。该N
命令通过用换行符分隔将下一行粘贴到模式空间\n
。现在,只有当 sed 能够删除模式空间中的 Active 第一行时,才会打印剩余的模式空间。这是有条件的打印。Otw nothing 并-n
应确保不会自动打印模式空间。HTH。您还可以使用范围运算符 of
Perl
并使用 a 对其进行约束,boolean condition
以处理{}
块中的嵌套括号。通常,人们会在
Perl
as中写入一个范围/re1/ ... /re2/
,这将导致perl
选择以 regex 开头/re1/
并在满足 regex 的行结束的块/re2/
。我们可以进一步限制这一点,例如:/re1/ ... /re2/ && $depth==0
。这将导致
perl
仅选择那些具有深度为零的附加约束的块。就像在这种情况下,只有当}
发现导致深度计数下降到零时,块结束才会发生,OTW,块累积也会继续超过这个标记。