【问题标题】:How to replace only on second matching row using sed如何使用 sed 仅在第二个匹配行上替换
【发布时间】:2018-05-31 12:45:06
【问题描述】:
$ cat file
cat cat
dog cat
dog puppy
dog cat

使用 sed:

$ sed 's/dog/big_dog/' my_file > new_file
cat new_file
cat cat 
big_dog cat
big_dog puppy
big_dog cat

我的目标是只用big_dog 替换第二个dog,但这不会发生在:

$ sed 's/dog/big_dog/2' my_file > new_file
cat
dog cat
dog puppy
dog cat

如何只替换第二次出现,即:

cat
dog cat
big_dog puppy
dog cat

【问题讨论】:

标签: linux unix sed


【解决方案1】:

sed 替代第二次出现的是:

sed "/dog/ {n; :a; /dog/! {N; ba;}; s/dog/big_dog/; :b; n; $! bb}" your_file

解释:

/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
}

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

【讨论】:

    【解决方案2】:

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

    $ sed '2s/dog/big_dog/' your_file
    dog cat
    big_dog puppy
    dog cat
    

    要将第二个匹配替换为 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
    

    【讨论】:

    • 工作得很好。你能指出我的文档吗?
    • Here,搜索部分 4 地址:选择行
    • 哦,不。有没有办法使它不特定于任何行?
    • @BishwasMishra,试试我的awk 代码,我在其中放置了一个可能有出现次数的变量,然后它会根据出现情况更改为该行,让我知道这是否对你有帮助?另外,请始终在您的帖子中一次性提及您的所有要求。
    • @RavinderSingh13 也许我应该说对不起......我发布了关于这个答案的评论(只是做第二行子)。但是,您认为我对您的评论发表了评论...在阅读了您的评论后,我认为这是 James 的回复...所以...您在此 sed 答案下再次解释了您的 awk 事情.. ^_*
    【解决方案3】:

    关注awk 在这里也可能对您有所帮助。

    awk -v line=2 '$1=="dog" && ++count==line{$1="big_dog"} 1'  Input_file
    

    如果将输出保存到 Input_file 本身,则在上面的代码中附加 > temp_file && mv temp_file Input_file

    解释:

    awk -v line=2 '             ##Creating an awk variable line whose value is 2 here.
    $1=="dog" && ++count==line{ ##Checking condition if $1 is dog and increasing variable count value is equal to value of line(then do following)
      $1="big_dog"}             ##Assigning $1 to big_dog here.
    1                           ##awk works on method of condition then action so by mentioning 1 I am making condition TRUE here so by default action print of line will happen.
    '  Input_file               ##Mentioning Input_file here.
    

    【讨论】:

      【解决方案4】:

      使用以下命令将第二行中的单词 dog 替换为 big_dog。

      # sed -i '2 s/dog/big_dog/g' my_file
      # cat my_file
      Output:-
      dog cat
      big_dog puppy
      dog cat
      

      相同如果你想从第 2 个替换到第 3 个,那么你可以使用下面的命令:-

      # sed -i '2,3 s/dog/big_dog/g' my_file
      

      【讨论】:

      • 希望它不是特定于行的。
      猜你喜欢
      • 2010-09-13
      • 1970-01-01
      • 2018-12-18
      • 2018-11-24
      • 2019-08-27
      • 2011-03-20
      • 2011-06-17
      相关资源
      最近更新 更多