在第n次出现后更换任何东西

时间:2015-01-27 21:33:32

标签: regex bash shell sed

我是Bash脚本的新手,并且一直在寻找一个正确的答案,我怎样才能在第n次出现后使用sed替换任何东西(不是替换第n次出现)。

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

有什么想法吗?

4 个答案:

答案 0 :(得分:2)

您可以使用:

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

答案 1 :(得分:1)

为什么不使用awk

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

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

答案 2 :(得分:0)

我会说

 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脚本中成为一个标记。 &指的是该行的匹配部分。

答案 3 :(得分:0)

正如我理解被问到的问题,如果您使用的是Unix 7th Edition shell或者基于它的更新的shell,比如sh或bash,这甚至都不需要sed或awk。只需使用set命令的一个不幸的模糊功能:

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

最初的问题是关于模式的问题,但提供的示例只有一个模式。空格的第二次出现隐含在第二个参数之后。我想,你可以使用一个小的贝壳算法使它适应“第n次出现”。

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