使用 SED 替换捕获的组

使用 SED 替换捕获的组

xxxxxx15 |xxxxxx02|RM99999 |xxxxxx |安库尔 |xxxxx |xxxxxxxx|M|xxxxxxxx| | | |xxxxxxx|xxx|xxxxxxxx| |10 |纽约| 23.00|周五|下午| | |不适用

想把10换成65,我衣柜里有的是sed -i '/^.\{20\}RM99999/ s/^\(?:[^|]*\|\)\{16\}\([^|]*\)/\165/' test.txt

但它用 65 替换第一个字符(可以在更多位置,但需要替换第 20 个字符RM99999的行)RM99999

答案1

看起来像一个 XY 问题。

为什么不尝试使用 awk 呢?

awk -F\| -v OFS=\| '$3=="RM99999" && $17 == 10 { $17=65 } {print ; } '

在哪里

  • -F\|告诉 awk 使用 |作为字段分隔符(\告诉 shell 转义|
  • -v OFS=\|告诉 awk 使用 |作为输出记录时的字段分隔符
  • $3=="RM99999" && $17 == 10选择第三行为 RM99999,第十七行为 10
  • $17 = 65替换为 65
  • { print ; }打印所有已更改和未更改的图案

答案2

sed '/^.\{19\}RM99999/s/10/65/' <in >out

将替换字符串第一次出现的位置10用字符串65在字符串所在的行上RM99999从第 20 个字符开始。

我猜有些人认为第 17 字段应该被替换。我真的不明白为什么,因为我在问题中看不到它,但如果这是你想要的......

sed '/^.\{19\}RM99999/s/[^|]*/65/17' <in >out

...这将|用字符串替换第 17 个分隔字段65在字符串所在的行上RM99999从第 20 个字符开始。

我只是在抓救命稻草,但也许它们的意思只是 10 并且只在第 17 场,并且只在RM99999从 20 个字符开始?有点难了...

sed -e'/^.\{19\}RM99999/s/|/|\n/16' \
    -e's/\n\([^|]*\)10/\165/;s/\n//' <in >out

...但是这样就可以了。仔细想想,确实看起来一点更像是你自己的代码。也许这就是我们最终想要的。

这个比较直接一点...

sed -e'/^.\{19\}RM99999/!b'    \
    -e's/|\([^|]*10\)*/&\n/16' \
    -e's/10\n/65/;s/\n//'

如果字段数是固定的,那么这一步就能完成。

sed -e'/^.\{19\}RM99999/s/10\([^|]*\(|[^|]*\)\{7\}\)$/65\1/'

当然,你可以从前端做同样的事情......

sed -e'/^.\{19\}RM99999/s/^\([^|]*\(|[^|]*\)\{16\}\)10/\165/'

但由于尾部的字段数量只有一半,如果有帮助的话,最好不要这样做。

使用扩展正则表达式语法编写起来更容易一些:

sed -Ee'/^.{19}RM99999/s/10([^|]*(\|[^|]*){7})$/65\1/'

相关内容