Regex 如何使用awk或sed替换特定配置文件下的特定单词

Regex 如何使用awk或sed替换特定配置文件下的特定单词,regex,bash,awk,sed,grep,Regex,Bash,Awk,Sed,Grep,文件包含以下格式的数据,现在我想更改XYZ节下showfirst的值。如何通过sed、awk或grep实现这一点 我想到了行号或第二个外观,但在未来的文件中这不会是常数,因为它可以包含数百个这样的配置文件,所以它必须是基于用户的 我知道我可以在“XYZ”模式后提取第一行,但我希望它是基于字段的。 谢谢你的帮助 [ABC] showfirst =0 showlast=10 [XYZ] showfirst=10 showlast=3 您可以像这样使用awk: awk -v val='50' 'B

文件包含以下格式的数据,现在我想更改XYZ节下showfirst的值。如何通过sed、awk或grep实现这一点

我想到了行号或第二个外观,但在未来的文件中这不会是常数,因为它可以包含数百个这样的配置文件,所以它必须是基于用户的

我知道我可以在“XYZ”模式后提取第一行,但我希望它是基于字段的。 谢谢你的帮助

[ABC]
showfirst =0
showlast=10

[XYZ]
showfirst=10
showlast=3

您可以像这样使用
awk

awk -v val='50' 'BEGIN{FS=OFS="="} /^\[.*\]$/{ flag = ($1 == "[XYZ]"?1:0) } 
       flag && $1 == "showfirst" { $2 = val } 1' file

[ABC]
showfirst =0
showlast=10

[XYZ]
showfirst=50
showlast=3
awk -v k=XYZ -v v=42 '$1 ~ "\\[" k "\\]" { sub("showfirst *=[^\n]*", "showfirst=" v) } 1' RS= ORS='\n\n' infile

在awk中。所有参数化:

$ awk -v l='XYZ' -v k='showfirst' -v v='666' '  # parameters lable, key, value
BEGIN { FS=OFS="=" }                            # delimiters
/\[.*\]/ { f=0 }                                # flag down @new lable
$1=="[" l "]" { f=1 }                           # flag up @lable
f==1 && $1==k { $2=v }                          # replace value when flag up and match
1' file                                         # print 
[ABC]
showfirst =0
showlast=10

[XYZ]
showfirst=666
showlast=3
伙计,我看了这些代码都感到困惑。

对于sed:

sed '/^\[XYZ\]/,/^showfirst *=/{0,//!s/.*/showfirst=20/}' file
工作原理:

  • /^[XYZ\]/,/^showfirst*=/
    :与从
    [XYZ]
    到下一个
    ^showfirst
    的行相匹配的地址范围
  • /
    用于匹配上述地址的行(
    [XYZ]
    showfirst=10
    )。所以
    0,//:不在第一个匹配行中(即
    showfirst=10
    行)
  • s/*/showfirst=20/
    :将行替换为
    showfirst=44

如果将记录分隔符(
RS
)设置为空搅拌,
awk
将一次读取整个记录,假设记录是双换行分隔的

例如,你可以这样做:

awk -v val='50' 'BEGIN{FS=OFS="="} /^\[.*\]$/{ flag = ($1 == "[XYZ]"?1:0) } 
       flag && $1 == "showfirst" { $2 = val } 1' file

[ABC]
showfirst =0
showlast=10

[XYZ]
showfirst=50
showlast=3
awk -v k=XYZ -v v=42 '$1 ~ "\\[" k "\\]" { sub("showfirst *=[^\n]*", "showfirst=" v) } 1' RS= ORS='\n\n' infile
输出:

[ABC]
showfirst =0
showlast=10

[XYZ]
showfirst=42
showlast=3

下面的命令为每个用户解决了我的问题

sed '/.*\[ABC\]/,/^$/ s/.*showfirst.*/showfirst=20/' input.conf
语法与sed[address]命令相同

“/.\[ABC\]/,/^$/
:这将生成地址范围,指向从[ABC]开始到下一个第一个空行的区域。仅在此特定范围内搜索字符串


s/*showfirst.*/showfirst=20/:
此搜索任何包含showfirst的行,并将整行替换为showfirst=20

请详细说明。此操作适用于XYZ配置文件,但当ABC的配置文件必须更改时,将显示以下输出,sed'/^[ABC]/,/^showfirst=/{0,//!s/*/showfirst=20/}input.conf[ABC]showfirst=20 showfirst=20 showfirst=20 showfirst=20 showfirst=20 showlast=3这是因为正则表达式与
showfirst=0
中的空格不匹配。我编辑过,现在应该可以了。如果每个部分只有一个
showfirst=
出现,这是正确的方法。(我不知道为什么,我认为可能会有多个
showfirst=
,并且只应该替换第一个出现的内容…)