【问题标题】:Replace first match after a match with sed用 sed 替换匹配后的第一个匹配
【发布时间】:2017-05-23 22:36:54
【问题描述】:

我想要实现的是在文件中找到一个字符串,然后继续寻找另一个匹配项的第一次出现并将其替换为某个值。

例如:字符串 = {Name: name;Address:someadd;var1:var1;var2:var2},{Name: differntName;Address:someadd;var1:var1;var2:var2}

现在我需要做的是找到名称:名称,然后在“名称:名称”之后找到第一次出现的“var2:var2”并将其替换为“var2:newvarvalue”

请注意,我需要在 bash 脚本中使用 sed 完成此任务。

提前致谢。

编辑:我正在尝试修改 .yaml docker compose 文件

【问题讨论】:

  • awk 可能是比sed 更好的选择
  • 感谢@KindStranger 的快速响应,但我需要在 sed 中执行此操作,但一旦我用完了选项,我可以考虑 awk。
  • 这是 JSON 数据吗?如果是这样,您最好使用jq 或其他专门的解析器。这与尝试使用 regex 解析 HTML 的论点相同;确保您可以很好地处理基本用例,但是您很快就会遇到一个边缘情况,这将使从一开始就使用专门的解析器获得巨大的时间收益。编辑:这不是 JSON 数据。如果存在的话,使用专门的解析器的要点仍然存在
  • @vinay 如果这是 yaml,我建议使用能够解析和修改 yaml 的编程语言。例如 Python。

标签: bash sed


【解决方案1】:

这是一个使用sed 的糟糕解决方案:

  1. , 上拆分,每行一个部分:

sed 's/,/\n/g'

  1. 如果与Name: name 在同一行,则将var2:var2 替换为var2:newvarvalue

sed '/Name: name/s/var2:var2/var2:newvarvalue/'

sed -E 's/(Name: name.*)var2:var2/\1var2:newvarvalue/'

这很糟糕,因为任何额外的逗号或换行符都可能破坏整个内容。

【讨论】:

  • 我忘记了第 3 步)将线条重新连接在一起,但我想这很明显。
【解决方案2】:
var='{Name: name;Address:somea,dd;var1:var1;var2:var2},{Name: differntName;Address:someadd;var1:var1;var2:var2}'

NEW_VAL='new_value'

IFS=$'\n'

OBJECTS=("$(echo "${var}" | sed -nE 's/[^{]*(\{[^}]+\})/\1\n/gp')")

for obj in "${OBJECTS[@]}"; do
  echo "${obj}" | sed -E 's/(.*var2:)(var2)(.*)/\1'"${NEW_VAL}"'\3/'
done

输出:

{Name: name;Address:somea,dd;var1:var1;var2:new_value}
{Name: differntName;Address:someadd;var1:var1;var2:new_value}

此解决方案通过提取每个逗号并将分隔符设置为换行符来解决对象中的逗号(如第一个对象中所示)

【讨论】:

    猜你喜欢
    • 2018-12-18
    • 2017-12-19
    • 2011-06-17
    • 2019-08-27
    • 1970-01-01
    • 2012-02-27
    • 2012-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多