如何使用 sed 命令替换指定范围内的单词出现?

如何使用 sed 命令替换指定范围内的单词出现?
str="I want to abc replace a word abc in a sentence abc of file abc by giving abc specifying a abc multiple abc range to abc the sed abc command abc."

上面的字符串 str 中有单词“abc”10倍发生,我想替换“abc”发生在2-4名时间和6-8名使用 sed 命令来处理单词“xyz”。

对字符串 str 执行 sed 命令后,str 应该如下所示:

str="I want to abc replace a word xyz in a sentence xyz of file xyz by giving abc specifying a xyz multiple xyz range to xyz the sed abc command abc."

答案1

我不确定它是否聪明,但这是我的 GNU sed 解决方案:

sed 's/abc/nonABC/5;s/abc/nonABC/8g;s/abc/xyz/2g;s/nonABC/abc/g' <<<"$str"

解释:

sed '
    s/abc/nonABC/5;   # replace only 5th occurrence of 'abc' word with another word (i, e: 'nonABC') 
    s/abc/nonABC/8g;  # replace 8th to the next occurrences of 'abc' with another word too
    s/abc/xyz/2g;     # replace all occurrences of 'abc' word start from 2th place
    s/nonABC/abc/g    # get back the all changed 'abc' from 'nonABC'
' <<<"$str"           # from 'str' as input

当然还有awk聪明的做法:

awk '{printf ( 2<=NR && NR<=8 && NR!=5 )?$0"xyz":$0RS}' RS='abc' <<<"$str"

解释:

  • RS='abc'将 'abc' 定义为R记录年代分离器
  • 如果数量Record 介于 2 和 8 之间2<=NR && NR<=8但不等于 5 NR!=5,则打印当前记录$0和替换词xyz,否则,打印记录及其abc本身。你可以$0"abc"代替使用$0RS.

如果你的范围如下: [(2-4),(8-10),(12-15),(18-20),(26-29) ...]你在评论中提到thenawk是这个任务的最佳命令。你只需要将范围指定为多个条件:

( (2<=NR && NR<=4) || (8<=NR && NR<=10) || (12<=NR && NR<=15) || (18<=NR && NR<=20) || (26<=NR && NR<=29) || (...) )

答案2

另一种方法是借助括号扩展,你可以这样做:

sed '-es/abc/xyz/'{8..6} '-es/abc/xyz/'{4..2} <<<"$str"

请注意,范围应该始终是max第一个,{max#..min#}甚至应该首先指定最大范围。

您还可以指定应在{x,y,z}格式中替换的位置范围,其中数字应该是x>y>z

sed '-es/abc/xyz/'{8,6,4,2} <<<"$str"

请注意,如果您使用相同的数字,{x,x}则会导致问题并会x一次又一次地替换位置(顺便说一下,还有s/abc/xyz/X另一种选择,X即位置编号)。


我从中学到Stéphane Chazelas 在 Unix.SE 上的回答

相关内容