【问题标题】:Replace 1st Occurence line with Value1 and 2nd Occurence line with Value2 using sed使用 sed 将第一个出现行替换为 Value1,将第二个出现行替换为 Value2
【发布时间】:2021-11-12 04:05:37
【问题描述】:

我坚持要求我必须用值 x 替换第一次出现的关键字{以及整行},用值 Y 替换第二次出现的关键字。例如

  1. sudo docker push IP:PORT/ABC:1

  2. sudo docker push IP:PORT/XYZ:1

在上述情况下,我会选择使用关键字“sudo docker push”并将第一次出现的整行替换为sudo docker push IP1:PORT/ABC:1,将第二次出现的整行替换为sudo docker push IP2:PORT/ABC:1

我尝试了以下组合,但到目前为止没有任何效果:

sed -i "s,old-word,new-word," file-name
sed -i "<occurence-number> s,old-word,new-word,g" file-name
sed -i " s,old-word,new-word,<occurence-number>g" file-name
sed "<occurence-number>,old-word,{s,old-word,new-word,}" file-name

【问题讨论】:

  • 输入字符串的输出究竟是什么?你的问题有点不清楚。
  • 第一次和第二次出现是什么意思?两个不同的字符串?一行请提供更清晰的示例
  • 简而言之,我想在“旧文本”第一次出现的地方用 Value1 替换整行,第二次出现整行时用 Value2 替换。希望它简化。

标签: linux bash awk sed


【解决方案1】:

示例不清楚...最好提供完整的字符串示例,说明您拥有的内容以及您想要的结果。 但也许你正在寻找“sudo docker push”并试图只替换这部分,而不是整行。 您可以使用正则表达式来选择行的其余部分,如下所示:

sed -i 's/sudo docker push.*/sudo docker push IP:PORT/XYZ:1/'

或者只是提供更清晰的来源和结果字符串示例。

【讨论】:

  • 是的,这个问题本来可以更好,但我发现以下两部分非常清楚 (1) »将第一次出现 [...] 替换为值 x和第二次出现,值为 Y。« 这似乎在您的答案中丢失。 (2) »替换 [...] 关键字{以及整行}« 或 »替换 [...] 出现的整行« 非常清楚地表明 OP 想要做与 »仅替换这部分而不是整行«相反的操作。
【解决方案2】:

如果您允许我重新表述您的问题:

名为file-name 的文件包含v.gr.

some lines
...
sudo docker push IP:PORT/ABC:1
more lines
...
sudo docker push IP:PORT/ABC:1
and so on
...

必须改成:

some lines
...
sudo docker push IP1:PORT/ABC:1
more lines
...
sudo docker push IP2:PORT/ABC:1
and so on
...

难点在于同一个key的两次出现必须触发两个不同的变化。

试试这个脚本:

#!/bin/bash

key="sudo docker push"
#Caution: "/" inside the two strings below must be escaped as "\/"
change1="sudo docker push IP1:PORT\/ABC:1"
change2="sudo docker push IP2:PORT\/ABC:1"

sed -i "
  0,/$key/s/^.*$key.*$/FIRST-OCCURENCE/
  0,/$key/s/^.*$key.*$/$change2/
  /FIRST-OCCURENCE/s//$change1/
" file-name

【讨论】:

    【解决方案3】:

    sed可以,但是很不方便:

    sed '/OLD/{s|.*|NEW-1|; :label; n; /OLD/s|.*|NEW-2|; b label;}'
    

    根据您的 sed 版本,您可能需要将 ; 替换为 :labelb label 之后的文字换行符才能使其正常工作。

    对于输入……

    a b c
    d OLD e
    f g h
    i OLD k
    l m n
    

    …这打印…

    a b c
    NEW-1
    f g h
    NEW-2
    l m n
    

    为简单起见,您可能想改用awk

    awk '/OLD/ {++c; if (c==1) {$0="NEW-1"} else {$0="NEW-2"}} 1'
    

    awk 'BEGIN {a[1]="NEW-1"; a[2]="NEW-2"} /OLD/ {$0=a[++c]} 1'
    

    【讨论】:

      【解决方案4】:

      试试这个

      sed -i "/old-word/c new-word" file-name
      

      【讨论】:

      • 引用问题,强调我的:»将第一次出现的 [...] 替换为值 x,第二次出现的替换为值 Y«
      【解决方案5】:

      awk 可用于替换第 4 列。

      awk '{x+=1; $4="IP"x":PORT/ABC:1"}1' $file
      

      这将增加x 每行

      输出

      sudo docker push IP1:PORT/ABC:1
      sudo docker push IP2:PORT/ABC:1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-14
        • 1970-01-01
        • 1970-01-01
        • 2019-04-19
        • 2013-12-22
        • 2015-05-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多