我有类似的命令输出
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
关于评论的一些解释,它是如何运作的
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=(.*+)/
(?:
..)
:非捕获组