【问题标题】:Bash - Update a value in a file using sed commandBash - 使用 sed 命令更新文件中的值
【发布时间】:2021-07-05 08:55:55
【问题描述】:

我正在尝试在以下文件中将 key1[count] 的值更新为 2。

#file1

//some additional lines
key1   = { var1 = "1", var2 = "12", "count" = 1 }
key2 = { var1 = "32", var2 = "23", "count" = 1 }
key3    = { var1 = "22", var2 = "32", "count" = 3 }
key4    = { var1 = "32", var2 = "12", "count" = 3 }
//some additional lines

我曾尝试使用 awk - awk -i inplace '{ if ( $1 == "key1" ) $12 = 2 ; print $0 }' file1。 但是,这只适用于 awk 版本 4.1.0 及更高版本。

【问题讨论】:

  • 您是在问如何根据需要更改值,或者如何将更改值的结果写回输入文件?你说this only works with... 所以我假设你的脚本实际上做了你想要的,你只是想用结果更新输入文件,对吗?请参阅stackoverflow.com/a/68228200/1745001,了解如何使用任何命令覆盖输入,如果您仍有疑问,请添加minimal reproducible example,其中包含简洁、可测试的示例输入和预期输出,以便我们为您提供帮助。

标签: awk sed


【解决方案1】:

使用您展示的示例,请尝试关注awk 代码。

awk -v newVal="2" '
/^key1/ && match($0,/"count"[[:space:]]+=[[:space:]]+[0-9]+/){
  value=substr($0,RSTART,RLENGTH)
  sub(/[0-9]+$/,"",value)
  $0=substr($0,1,RSTART-1) value newVal substr($0,RSTART+RLENGTH)
}
1
'  Input_file

解释: 检查条件是否从key1 开始,并使用match 函数匹配正则表达式"count"[[:space:]]+=[[:space:]]+[0-9]+ 以获取计数字符串及其值。然后使用匹配的子字符串创建值(变量),其中将值的最后数字替换为 NULL。然后将当前行的值重新分配给匹配值之前、匹配值、新值变量和行的其余部分,以使其符合 OP 的要求。最后由1 打印当前行。

注意:上面只会在终端上打印输出,一旦您对显示的结果感到满意,请将 > temp && mv temp Input_file 附加到上面的代码中。

【讨论】:

  • 试过上面的命令_key1 = { var1 = "1", var2 = "12", "count" = 1 }好像没有用2替换值。
  • @SushmaKamat,正如我的回答中提到的,这将在终端上打印所有文件值。一旦您对结果感到满意,请仅在我的代码中使用 -i inplace。如果您想使用一个班轮,请尝试awk -v newVal="\"2\"" '/^key1/ && match($0,/"count"[[:space:]]+=[[:space:]]+[0-9]+/){value=substr($0,RSTART,RLENGTH);sub(/[0-9]+$/,"",value);$0=substr($0,1,RSTART-1) value newVal substr($0,RSTART+RLENGTH)} 1' file 一次,然后让我知道(与发布的代码相同,但以一个班轮形式),让我知道它是怎么回事?
  • 主要目的是删除-i inplace的使用。这仅适用于具有更高版本 awk(即 4.1.0 和更高版本)的机器。使用 awk -i inplace 会出错 - awk: unknown option -i ignored
  • @SushmaKamat,哦,好吧,然后像这样使用:awk -v newVal="2" '/^key1/ && match($0,/"count"[[:space:]]+=[[:space:]]+[0-9]+/){value=substr($0,RSTART,RLENGTH);sub(/[0-9]+$/,"",value);$0=substr($0,1,RSTART-1) value newVal substr($0,RSTART+RLENGTH)} 1' file > temp && mv temp file 一次,让我知道进展如何?
  • 当然!!感谢您的所有帮助
【解决方案2】:

您可以将sed-r 选项一起用于正则表达式。

对于您的示例,您可以使用此命令。

sed -i -r 's/(key1.*"count" = )([0-9]*)(.*)/\12\3/g' <file>

更多信息:

Command template:
    sed -i -r 's/(<bef>)(<tar>)(<aft>)/\1<new value>\3/g' <file>

Where
    <bef> is a regex that targets /key1... "count" = /
    <tar> is a regex that targets /1/
    <aft> is a regex that targets / }/

Together, /<bef><tar><aft>/ will expand to become:
    /key1   = { var1 = "1", var2 = "12", "count" = 1 }/

Since you want to replace "1" with "2"
    <new value> is 2

【讨论】:

  • 谢谢。这行得通!你能解释一下3的用法吗?
  • \1\2\3 是反向引用,可用于访问正则表达式 &lt;bef&gt;&lt;tar&gt;&lt;aft&gt; 捕获的实际文本。
  • 非常感谢您的详细解释!我不介意凌乱的回复:P
猜你喜欢
  • 2021-12-18
  • 2021-10-17
  • 1970-01-01
  • 2011-04-28
  • 2015-04-16
  • 2022-10-25
  • 2014-06-13
  • 2019-04-12
  • 1970-01-01
相关资源
最近更新 更多