使用 SED 替换捕获的组

ank*_*kur 3 sed

xxxxxx15 |xxxxxx02|RM99999 |xxxxx |Ankur |xxxxx |xxxxxxxx|M|xxxxxxxx| | | |xxxxxxxx|xxx|xxxxxxxx| |10 |纽约| 23.00|F|P| | |不适用

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

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

Arc*_*mar 5

看起来像XY问题。

为什么不试试 awk 呢?

awk -F\| -v OFS=\| '$3=="RM99999" && $17 == 10 { $17=65 } {print ; } '
Run Code Online (Sandbox Code Playgroud)

在哪里

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


mik*_*erv 5

sed '/^.\{19\}RM99999/s/10/65/' <in >out
Run Code Online (Sandbox Code Playgroud)

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

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

sed '/^.\{19\}RM99999/s/[^|]*/65/17' <in >out
Run Code Online (Sandbox Code Playgroud)

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

我有点想抓住稻草,但也许他们的意思是只有 10 个,而且只在第 17 个字段中,并且只在RM99999开始 20 个字符的行中?难度有点大...

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

……但这会做到的。试想想它,它看起来有点更像你自己的代码。也许这毕竟是想要的。

这个比较直接...

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

这是一次性完成的 - 如果字段数是固定的,那就是。

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

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

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

但是由于尾部有一半的字段,如果可以帮助它可能最好不要。

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

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