【问题标题】:sed replace anything after nth occurencesed 在第 n 次出现后替换任何内容
【发布时间】:2015-01-27 21:33:32
【问题描述】:

我是 Bash 脚本的新手,一直在寻找正确的答案,以了解如何在第 n 次出现后使用 sed 替换任何内容(而不是替换第 n 次出现)。

例如,如果我想更改第二个空格之后的任何内容,我会输入以下句子:Today is a good day,结果是以下句子:Today is a friday

有什么想法吗?

【问题讨论】:

  • 但是good 在第三个空格之后而不是第二个

标签: regex bash shell sed


【解决方案1】:

你可以使用:

s='Today is a good day'
echo "$s" | sed 's/^\(\([^[:space:]]\+[[:space:]]\+\)\{3\}\)[^[:space:]]\+[[:space:]]\+/\1fri/'
Today is a friday

使用-r进行简化:

cho "$s" | sed -r 's/^((\S+\s+){3})\S+\s+/\1fri/'
Today is a friday

【讨论】:

  • 感谢您的回答,但我想说这对初学者来说太复杂了!
  • @anubhava 您能否在答案的第一部分中对 sed 的结构进行一些描述?
  • 其实第一个和第二个种子命令是一样的。唯一的区别是第一个种子使用 POSIX 属性 [[:blank:]] 匹配空格或制表符。如果没有-r,我们需要转义括号以捕获组。
【解决方案2】:

为什么不直接使用awk

echo "Today is a good day" | awk '{print $1,$2,"a friday"}'
Today is a friday

这将保留前两个字段,并替换该行的其余部分。

【讨论】:

    【解决方案3】:

    我会说

     echo 'Today is a good day.' | sed 's/ /&\n/3; s/\n.*/friday/'
    

    这由两个命令组成:

    s/ /&\n/3       # inserts a \n after the third space
    s/\n.*/friday/  # replaces \n and everything that comes after it with "friday"
    

    这利用了\n 永远不会出现在一行中的事实——这使得\n 在sed 脚本中非常适合作为标记。 & 指的是该行的匹配部分。

    【讨论】:

    • 我也有同样的想法,但无法通过..您的回答很有帮助!
    【解决方案4】:

    据我了解,如果您使用的是 Unix 第 7 版 shell 或基于它的新 shell(如 sh 或 bash),这甚至不需要 sed 或 awk。只需使用 set 命令的一个不幸的晦涩功能:

    $ set Today is a good day
    $ echo $1 $2 "Friday"
    Today is Friday
    

    最初的问题是关于模式的,但提供的示例中模式只是一个空格。空格的第二次出现隐含在第二个参数之后。我想,您可以使用一点 shell 算法将其调整为“第 n 次出现”。

    这个套路已经存在了很长时间,尽管我最近才发现它。 Kernighan 和 Pike 的“The UNIX Programming Environment”(1984 年)的第 136 页显示了它的使用示例。它在 Bash 上的工作原理相同,我猜它必须出现在任何第 7 版中。贝壳衍生物。

    【讨论】:

      猜你喜欢
      • 2011-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-16
      相关资源
      最近更新 更多