Regex 使用sed进行模式匹配后的多行模式
我有一个由多个部分组成的配置文件,其中许多部分包含一个同名的属性,让它成为Regex 使用sed进行模式匹配后的多行模式,regex,bash,unix,sed,Regex,Bash,Unix,Sed,我有一个由多个部分组成的配置文件,其中许多部分包含一个同名的属性,让它成为host。我只需要替换一个特定节的host属性。以下是文件: section1 { ... setting1 = "true" ... host = "localhost" ... } section2 { ... host = "whatever" ... } 我想用其他内容替换section2的host值。请注意,中间可能有任意数量的行,标记为… sed -i.bak '/^secti
host
。我只需要替换一个特定节的host
属性。以下是文件:
section1 {
...
setting1 = "true"
...
host = "localhost"
...
}
section2 {
...
host = "whatever"
...
}
我想用其他内容替换section2
的host
值。请注意,中间可能有任意数量的行,标记为…
sed -i.bak '/^section2 {/,/^}/s/host .*/host = "newvalue"/' file
这将在部分2{
和下一个}
之间进行搜索,更改所有主机=
事件。GNU sed语法,您应该在OSX上使用egsed-i'.
这将在
部分2{
和下一个}
之间进行搜索,更改所有主机=
事件。GNU sed语法,您应该在OSX上使用例如sed-i'.
。awk
来拯救它
$ awk 'BEGIN{RS=ORS="\n}"}
/section2/{sub("host =[^\n]*", "host = \"newvalue\"")}NF' file
section1 {
...
setting1 = "true"
...
host = "localhost"
...
}
section2 {
...
host = "newvalue"
...
}
定义记录结构,找到相应的记录并替换。
awk
救援
$ awk 'BEGIN{RS=ORS="\n}"}
/section2/{sub("host =[^\n]*", "host = \"newvalue\"")}NF' file
section1 {
...
setting1 = "true"
...
host = "localhost"
...
}
section2 {
...
host = "newvalue"
...
}
定义记录结构,找到相应的记录并替换。可能是最佳选择
要用awk
解决方案(一种经过校正的、更健壮的版本)对其进行补充:
- 使用GNU
:谢谢awk
- 使用
(不太健壮;也可以使用GNUmawk
):awk
RS
值,两种解决方案均不适用于BSD/OSXawk
;要让它在那里发挥作用需要付出更多的努力
说明:
告诉RS=ORS=“}\n”
按awk
实例将输入拆分为记录(通过特殊变量}\n
,输入记录分隔符),并对输出使用相同的分隔符(通过RS
,输出记录分隔符)ORS
在每条记录的开头匹配literal/^section2/
section
- Mawk解决方案:
用新值替换key{sub(/host=[^\n]*/,“host=\“new value\”)}
的值host
- 请注意,只需要匹配下一个换行符
,因为只要([^\n]*)
就可以跨换行符匹配到记录的末尾*
- 最好更可靠地匹配
键,例如使用主机
),但您需要捕获组引用以在替换值中保留相同数量的前面空白,而sub(“/(\n*host=)…
不支持该值。sub()
然而,GNU
确实通过其非标准的awk
函数提供捕获组引用;请参见下文gensub()
- 请注意,只需要匹配下一个换行符
- GNU Awk解决方案:使用非标准的
函数可以使用捕获组(gensub()
表示第一个捕获组,…),这使得替换更加健壮和方便\\1
,不同于gensub()
,gensub()不修改输入字符串,而是返回修改后的副本-因此需要将其分配给sub()
$0
第三个参数告诉1
仅替换1个匹配项gensub()
- Mawk解决方案:
是一种常用的速记,用于简单地打印生成的记录1
- 可能是最好的选择
要用
awk
解决方案(一种经过校正的、更健壮的版本)对其进行补充:
- 使用GNU
:谢谢awk
- 使用
(不太健壮;也可以使用GNUmawk
):awk
RS
值,这两种解决方案都不适用于BSD/OSXawk
;在那里工作需要更多的努力
说明:
告诉RS=ORS=“}\n”
按awk
实例将输入拆分为记录(通过特殊变量}\n
,输入记录分隔符),并对输出使用相同的分隔符(通过RS
,输出记录分隔符)ORS
在每条记录的开头匹配literal/^section2/
section
- Mawk解决方案:
用新值替换key{sub(/host=[^\n]*/,“host=\“new value\”)}
的值host
- 请注意,只需要匹配下一个换行符
,因为只要([^\n]*)
就可以跨换行符匹配到记录的末尾*
- 最好更可靠地匹配
键,例如使用主机
),但您需要捕获组引用以在替换值中保留相同数量的前面空白,而sub(“/(\n*host=)…
不支持该值。sub()
然而,GNU
确实通过其非标准的awk
函数提供捕获组引用;见下文gensub()
- 请注意,只需要匹配下一个换行符
- GNU Awk解决方案:使用非标准的
函数可以使用捕获组(gensub()
表示第一个捕获组,…),这使得替换更加健壮和方便\\1
,不同于gensub()
,gensub()不修改输入字符串,而是返回修改后的副本-因此需要将其分配给sub()
$0
第三个参数告诉1
仅替换1个匹配项gensub()
- Mawk解决方案:
是一种常用的速记,用于简单地打印生成的记录1
-I
,但是是的,这非常有效。非常感谢。我还必须添加-I
,但是是的,这非常有效。非常感谢。很有希望,但是(a)它打印了一个额外的
awk '
BEGIN{ RS=ORS="}\n" }
/^section2/ { sub(/ host = [^\n]*/, " host = \"new value\"") }
1' file