假设以下结构:
- key1: value11
key2:
- value21
- value22
- value23
key3: value31
key4:
- value41
- value42
key5: value51
- key1: value12
key2:
- value24
- value25
key3: value32
key5: value52
- key1: value13
key2:
- value26
key3: value33
key4:
- value43
- value44
- value45
key5: value53
是否有可能删除开始标记和结束标记正则表达式之间(并包括)之间的所有块:
- begin marker: '^[[:blank:]]{2}-[[:blank:]]{3}key1:[[:blank:]].+$'
- end marker: '^[[:blank:]]{6}key5:[[:blank:]].+$'
当以下正则表达式在块内匹配时:
matching pattern: '^[[:blank:]]{6}key3:[[:blank:]]value32$'?
目标是获得:
- key1: value11
key2:
- value21
- value22
- value23
key3: value31
key4:
- value41
- value42
key5: value51
- key1: value13
key2:
- value26
key3: value33
key4:
- value43
- value44
- value45
key5: value53
开始标记还可以用作结束标记,因为在删除块期间未删除第二个标记。
我未成功使用sed / awk尝试多种方法,例如在post处从4.21段落启发而来的这种方法:
sed ':t
/^[[:blank:]]{2}-[[:blank:]]{3}key1:[[:blank:]].+$/,/^[[:blank:]]{6}key5:[[:blank:]].+$/ { # For each line between these block markers
/^[[:blank:]]{6}key5:[[:blank:]].+$/!{ # If we are not at the /end/ marker
$!{ # nor the last line of the file
N; # add the Next line to the pattern space
bt
} # and branch (loop back) to the :t label
} # This line matches the /end/ marker
/^[[:blank:]]{6}key3:[[:blank:]]value32$/d; # If /regex/ matches, delete the block
}' file
sed是对单个字符串执行s/old/new/
的正确工具,仅此而已。对于更有趣的事情,您应该使用awk以获得清晰度,可移植性,鲁棒性,效率等。
您实际上不需要给定您发布的示例输入/输出所指定的第一个条件,例如使用GNU awk进行多字符RS和RT:
awk -v RS='[[:blank:]]{6}key5:[[:blank:]][^\n]+\n' -v ORS= '
!/\n[[:blank:]]{6}key3:[[:blank:]]value32\n/{ print $0 RT }
' file
- key1: value11
key2:
- value21
- value22
- value23
key3: value31
key4:
- value41
- value42
key5: value51
- key1: value13
key2:
- value26
key3: value33
key4:
- value43
- value44
- value45
key5: value53
或任何awk:
awk '
{ rec = rec $0 ORS }
/^[[:blank:]]{6}key5:[[:blank:]].+$/ {
if ( rec !~ /\n[[:blank:]]{6}key3:[[:blank:]]value32\n/ ) {
printf "%s", rec
}
rec=""
}
' file
- key1: value11
key2:
- value21
- value22
- value23
key3: value31
key4:
- value41
- value42
key5: value51
- key1: value13
key2:
- value26
key3: value33
key4:
- value43
- value44
- value45
key5: value53
但是您可以根据需要使用它:
awk '
/^[[:blank:]]{2}-[[:blank:]]{3}key1:[[:blank:]].+$/ { inBlock=1 }
inBlock { rec = rec $0 ORS }
/^[[:blank:]]{6}key5:[[:blank:]].+$/ {
if ( rec !~ /\n[[:blank:]]{6}key3:[[:blank:]]value32\n/ ) {
printf "%s", rec
}
rec=""
inBlock=0
}
' file
- key1: value11
key2:
- value21
- value22
- value23
key3: value31
key4:
- value41
- value42
key5: value51
- key1: value13
key2:
- value26
key3: value33
key4:
- value43
- value44
- value45
key5: value53