sed 在模式中保留通配符值

sed preserve wildcard value inside pattern

我有一些应用程序配置文件 tmp.cfg。并且需要改变里面的一些给定值。 以下是字符串示例:

app-stat!error!25871a5f-9f50-40ac-923d-c80a660fe21d!1!2
app-stat!queued!25871a5f-9f50-40ac-923d-c80a660fe21d!5!10
app-stat!error!fbbf0e80-8a21-4ebf-9a78-b1017c58a19d!1!2
app-stat!error!5670b363-6a5d-4fcd-819e-85786c5957f1!120!200

对于包含
的所有字符串 !error! 然后跟随一些 GUID 然后值 !1!2 更改为
!error! 然后保留一些 GUID,然后保留新值 !7!10
我不需要触摸其他包含 !error! 然后是 GUID 但最后包含不同值的字符串

这是我尝试过的:
sed -i "s/error\!.*\!1\!2/error\!.*\!4\!8/g" tmp.cfg
它找到了我需要的所有字符串,但实际上用符号 .* 而不是 GUID 编号本身替换了 GUID。 如何以这种方式构建 sed 表达式以保留通配符部分?

预期结果为: app-stat!error!fbbf0e80-8a21-4ebf-9a78-b1017c58a19d!4!8
实际结果是: app-stat!error!.*!4!8

这个 sed 命令应该有效:

sed -r 's/(.*)!error!(.*)!1!2$/!error!!4!8/g' file_name
sed 's/\(!error!.*\)!1!2/!4!8/g' file

我猜你需要这样的东西。

内包含的模式
\( ... \)

保存在寄存器中供以后使用,可以作为 </code>、<code> … 直到 </code>.</p> 访问 <p>在上面的 <code>sed 表达式中,来自 !error!<GUID> 的模式在 </code> 中被捕获并在替换为 <code>!4!8 时使用。

如果您确定同一模式不会在一行中出现两次,则可以从 sed 表达式中省略 g

这很容易做到 awk

awk '=="error" && ==1 && ==2 {=7;=10}1' FS="!" OFS="!" file
app-stat!error!25871a5f-9f50-40ac-923d-c80a660fe21d!7!10
app-stat!queued!25871a5f-9f50-40ac-923d-c80a660fe21d!5!10
app-stat!error!fbbf0e80-8a21-4ebf-9a78-b1017c58a19d!7!10
app-stat!error!5670b363-6a5d-4fcd-819e-85786c5957f1!120!200
  • !
  • 分隔字段
  • 那么如果字段2=error,字段4=1和字段5=1
  • 将字段 45 设置为 710
  • 1 打印行