解释:

解释:

所以我有一个像这样的文件

[ABC]
value1=bla
value2=bla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla

我想用“value1=notbla”替换 [ABC] 块下的 value1,而不是 [XYZ] 块下的 value1。我已经尝试过了

sed '/ABC/{n;s/.*/change/}'  file

但这仅在尝试转到下一行时有效,并且不会更改特定模式(即,如果 value1 低于值 2) 如果我不知道特定行号,我可以使用什么 sed 或 awk 命令。您能否标出所使用的每个 sed 或 awk 标签的功能。我真的很感激。

答案1

sed 可以很容易地处理这个问题。这是一个单一的“替代”命令,以地址范围为前缀。我添加了额外的间距以提高可读性:

sed -e '/^\[ABC\]$/ , /^\[.*\]$/     s/^\(value1=\).*$/\1notbla/'

没有额外的间距,它是:

sed -e '/^\[ABC\]$/,/^\[.*\]$/s/^\(value1=\).*$/\1notbla/'

您实际上并不需要锚定正则表达式,但在某些异常输入的情况下它们可能更安全。带有未锚定正则表达式的稍微较短的版本是:

sed -e '/\[ABC\]/,/^\[/s/^\(value1=\).*$/\1notbla/'

解释:

您要求对每个标志或选项进行解释,我有时间,所以您开始吧。我正在解释上面列出的三个 Sed 命令中的最终(最短)版本。

该行的第一部分是地址范围:地址范围后面的 ubstitute/startregex/,/stopregex/ 命令s仅适用于从startregexstopregex(含)的行。

在这种情况下,起始正则表达式是/\[ABC\]/.方括号通常是正则表达式中的特殊字符,因此我们在每个字符之前添加反斜杠来表示文字方括号字符。

停止正则表达式是/^\[/,它使用特殊的正则表达式字符^来表示行的开头。此模式将匹配任何以左方括号 ( [) 开头的行。

替代命令s基本上非常简单;一般格式是s/findregex/replacetext/.它还可以在 Final 之后放置特殊标志/来修改其行为,但我在这里没有使用任何此类标志。

“查找正则表达式”是^\(value1=\).*$.

^如前所述,插入符号 ( ) 匹配行的开头,而美元符号 ( $) 匹配行的结尾。因此,整个模式必须匹配整行,而不仅仅是一行的一部分。

()与方括号不同,括号 ( ) 是-special 在正则表达式中默认是特殊的,所以我们在它们前面加上反斜杠来赋予它们特殊的含义。它们允许在替换文本中使用部分匹配文本(与“查找正则表达式”匹配的文本)。具体来说,\1替换文本中的 表示“在正则表达式中第一组括号内匹配的文本”。在这种情况下,始终只是“value1=”。

“查找正则表达式”中的最后一个元素是.*。点 ( .) 表示“任何单个字符”,星号 ( *) 表示“任意次数(零次或多次)”。因此,点星号 ( .*) 与等号之后的该行的整个其余部分相匹配。

替换文本中的“notbla”只是静态文本,没有什么特别的。


要真正正确地学习 Sed,我强烈推荐Grymoire Sed 教程,这是免费的在线。

答案2

awk '
  BEGIN {FS=OFS="=";}
  /\[.*\]/ {if ($0 == "[ABC]") edit=1; else edit=0;}
  {if (edit && $1 == "value1" ) $2="notbla";}1
' file 

答案3

另一种awk解决方案

$ cat ip.txt 
[ABC]
value1=bla
value2=bla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla

如果行以[指定一个标志开头,则该标志将根据块名称设置或清除。然后如果设置了标志,则进行替换

$ awk '/^\[/{f=/\[ABC\]/} f{sub("value1=bla","value1=nobla")} 1' ip.txt 
[ABC]
value1=nobla
value2=bla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla


中的类似解决方案perl,更改了演示的替代

$ perl -pe '$f=/\[ABC\]/ if /^\[/; s/value2=bla/value2=nobla/ if $f;' ip.txt 
[ABC]
value1=bla
value2=nobla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla


=如果无论是否具体匹配到 ,都必须更改 右侧的所有内容bla,请使用

awk '/^\[/{f=/\[ABC\]/} f{sub(/value1=.*/,"value1=nobla")} 1' ip.txt 
perl -pe '$f=/\[ABC\]/ if /^\[/; s/value2=.*/value2=nobla/ if $f;' ip.txt

相关内容