【问题标题】:sed replace second occurrence in file not workingsed 替换文件中的第二次出现不起作用
【发布时间】:2021-12-29 10:20:37
【问题描述】:

我正在使用 centos 7. sed 命令替换 second 事件对我不起作用。 我尝试了以下解决方案 - Sed replace at second occurrence Sed/Awk to delete second occurence of string - platform independent sed: How to delete second match in a file https://unix.stackexchange.com/questions/18303/sed-delete-all-occurrences-of-a-string-except-the-first-one

文件 -

this
foo
is
a test
file
this
foo

我正在尝试运行 -

sed 's/foo/bar/2g' file
sed 's/foo/bar/2' file
sed -i 's/foo/bar/2g' file

我希望用第二个中的“bar”替换所有出现的“foo”。

【问题讨论】:

  • 您试图模拟的答案旨在替换模式在每一行中的第二次出现。它不包含用于跟踪多行模式出现的机制或逻辑。
  • 您想只替换整个文件中的第二个外观吗?或者,也许每个偶数出现?还是第二次和所有随后的出场?你能假设至少会出现两次吗?你能假设正好有两个吗?

标签: bash sed centos


【解决方案1】:

这将对包含指定模式 (/foo/) 的第二行和所有后续行执行替换:

sed ':1; /foo/! { n; b1 }; :2; n; s/foo/bar/; b2' file

它有两个部分:

  • :1; /foo/! { n; b1 }; 是一个循环,读取行并将它们原样输出,直到遇到与 /foo/ 匹配的第一行。
  • :2; n; s/foo/bar/; b2 是一个循环,重复输出当前行,读取下一行并执行替换 s/foo/bar/。对于不包含该模式的行,替换是无害的无操作。

模式的第一个匹配是第二个循环开始时的当前行,所以当第二个循环第一次执行它的n命令时输出不变。

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed):

    sed -z 's/foo/bar/2' file
    

    将整个 for 文件拖入模式空间,并将第二次出现的 foo 替换为 bar

    替代方案:

    sed 'H;$!d;x;s/.//;s/foo/bar/2' file 
    

    【讨论】:

    • 第一个非常好。
    • 对于从第二个开始的所有事件,然后在替换命令上使用g 标志。
    猜你喜欢
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 2016-04-02
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    相关资源
    最近更新 更多