【问题标题】:sed conditionally append to line after matching patternsed 在匹配模式后有条件地附加到行
【发布时间】:2019-04-11 13:38:55
【问题描述】:

我有一个包含以下内容的文件(测试)需要编辑。

测试

foo:
bar:hello

我目前正在使用 sed 来匹配一个模式并将一个字符串附加到行尾。

sed -ie "/^bar/ s/$/,there" test

这给了我预期的输出,即

foo:
bar:hello,there

但问题是,当行不以: 结尾时,逗号 (,) 应该在那里。否则会变成这样:

sed -ie "/^foo/ s/$/,there" test

输出:

foo:,there
bar:hello

要求:

foo:there
bar:hello

那么是否可以通过任何方式检查模式,在匹配后检查行的最后一个字符,根据最后一个字符,在行尾附加一个字符串。

P.S.:我无法安装单独的包。

【问题讨论】:

  • 如果你想将“there”附加到“foo:”行,那为什么还要检查“bar”呢?
  • “foo”或“bar”作为输入。所以我在一个变量中接收它并在 sed 中使用该变量。

标签: bash shell unix awk sed


【解决方案1】:

保持简单,只需使用 awk:

$ awk '/^foo/{$0 = $0 (/:$/ ? "" : ",") "there"} 1' file
foo:there
bar:hello

$ awk '/^bar/{$0 = $0 (/:$/ ? "" : ",") "there"} 1' file
foo:
bar:hello,there

请注意所有原始字符串(foobar)、:,$ 和替换文本(there)都只指定一次吗?这是您在软件中想要的东西之一 - 最小冗余。

以上内容可以在任何 UNIX 机器上的任何 shell 中使用任何 awk。

【讨论】:

  • 虽然答案比 sed 简单,但 awk 需要额外的工作来将更改写入同一个文件,而使用 sed 更容易。
  • @RatDon 就像 GNU sed 有 -i,GNU awk 有 -i inplace 做同样的事情。
【解决方案2】:

这是在成功替换后使用t 以从第二个s/// 命令分支的一种方法:

$ cat test
foo:
bar:
bar:hello
bar:
bar:hello
bar:
bar:hello

$ sed '/^bar/ {s/:$/:there/;t;s/$/, there/}' test 
foo:
bar:there
bar:hello, there
bar:there
bar:hello, there
bar:there
bar:hello, there

【讨论】:

    【解决方案3】:

    您的 sed 命令前面的模式是您的条件。您应该知道您可以为 sed 指定多个 -e 命令。

    这又是你的代码,但我忽略了 foo 和 bar。我只关注最后一个字符:

    sed -i -e '/[^:]$/s/$/,there/' -e '/:$/s/$/there/' test
    

    /[^:]$/ 是任何在行尾不是冒号的字符。 /:$/ 是补码(任何以冒号结尾的行)。

    结果如下:

    $ sed  -e '/[^:]$/s/$/,there/' -e '/:$/s/$/there/' test
    foo:there
    bar:hello,there
    

    【讨论】:

      【解决方案4】:

      两者都尝试 gnu sed,

      sed -E '/^(foo|bar)/ s/:$/&there/;n; s/[^:]$/&,there/' test
      

      【讨论】:

        猜你喜欢
        • 2016-08-27
        • 2022-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多