如何使用 sed 仅替换第二个匹配行

Bis*_*hra 4 unix linux sed

$ cat file
cat cat
dog cat
dog puppy
dog cat
Run Code Online (Sandbox Code Playgroud)

使用 sed:

$ sed 's/dog/big_dog/' my_file > new_file
$ cat new_file
cat cat 
big_dog cat
big_dog puppy
big_dog cat
Run Code Online (Sandbox Code Playgroud)

我的目标是仅替换第二个,dog但这big_dog并没有发生:

$ sed 's/dog/big_dog/2' my_file > new_file
cat
dog cat
dog puppy
dog cat
Run Code Online (Sandbox Code Playgroud)

我怎样才能只替换第二次出现的情况,即:

cat
dog cat
big_dog puppy
dog cat
Run Code Online (Sandbox Code Playgroud)

Haz*_*d17 8

sed第二次出现的替换是:

sed "/dog/ {n; :a; /dog/! {N; ba;}; s/dog/big_dog/; :b; n; $! bb}" your_file
Run Code Online (Sandbox Code Playgroud)

解释:

/dog/ {           # find the first occurrence that match the pattern (dog)
  n               # print pattern space and read the next line
  :a              # 'a' label to jump to
  /dog/! {        # if pattern space not contains the searched pattern (second occurrence)
    N             # read next line and add it to pattern space
    ba            # jump back to 'a' label, to repeat this conditional check
  }               # after find the second occurrence...
  s/dog/big_dog/  # do the substitution
  :b              # 'b' label to jump to
  n               # print pattern space and read the next line
  $! bb           # while not the last line of the file, repeat from 'b' label
}
Run Code Online (Sandbox Code Playgroud)

请注意,在找到第二次出现后,需要最后 3 个命令来打印文件的其余部分,否则可能会对搜索模式的每个偶数出现重复替换。


Jam*_*own 7

就像评论中讨论的那样,这个替换了第二行的匹配:

$ sed '2s/dog/big_dog/' your_file
dog cat
big_dog puppy
dog cat
Run Code Online (Sandbox Code Playgroud)

要用 sed 替换第二个匹配项,请使用:

sed ':a;N;$!ba;s/dog/big_dog/2'   your_file_with_foo_on_first_row_to_demonstrate
foo
dog cat
big_dog puppy
dog cat
Run Code Online (Sandbox Code Playgroud)