多行匹配:提取单独的行

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

我有类似的命令输出

var="""
Name=<Some name>
    key1=value1
    key2=value2 key3=value3
    key4=value4

Name=<Some other name>
    key1=val1
    key2=val2 key3=val3
    key4=val4

"""

参见例如

scontrol show partition
的输出。

如何从这些多行字符串中提取某个键值对?

我可以,例如使用

sed
来匹配一个块 via

echo "${var}" | | sed -n '/^Name=/,/^\s+key4=/p'

这给了我整个区块(这里什么也没得到)

如何获得类似的输出

<Some name>: key4=value4
<Some other name>: key4=val4

<Some name>: key3=value3
<Some other name>: key3=val3
sed multiline slurm
1个回答
0
投票

关于评论的一些解释,它是如何运作的

perl -00ne 'print"$1: $2\n" if /^Name=(.*)(?s:.)*^\s+key4=(.*)/m'

来自命令行帮助

perl -h

-0[octal]         specify record separator (\0, if no argument)

此处 0 特殊情况“段落模式”(两个或多个连续的换行符将充当记录分隔符)。

-n                assume "while (<>) { ... }" loop around program
-e program        one line of program (several -e's allowed, omit programfile)

关于表达式,在本例中 if 修饰符更短一行,但与

相同
if (/^Name=(.*)(?s:.)*^\s+key4=(.*)/m) {
   print "$1: $2\n";
}

关于正则表达式,捕获组

(.*)
匹配除换行符之外的任何字符
.
非捕获组
s
..
(?s:
内的
)
标志更改了
.
的含义以匹配换行符。
m
标志允许
^
也匹配换行符之后的位置。

关于回溯,由于存在多个

*
量词,正则表达式可能会出现灾难性的回溯,多一些量词来防止回溯,可以改进正则表达式:

/^Name=(.*+)(?:.*+\n)*?\s+key4=(.*+)/

(?:
..
)
:非捕获组

© www.soinside.com 2019 - 2024. All rights reserved.