【发布时间】:2015-01-27 21:33:32
【问题描述】:
我是 Bash 脚本的新手,一直在寻找正确的答案,以了解如何在第 n 次出现后使用 sed 替换任何内容(而不是替换第 n 次出现)。
例如,如果我想更改第二个空格之后的任何内容,我会输入以下句子:Today is a good day,结果是以下句子:Today is a friday
有什么想法吗?
【问题讨论】:
-
但是
good在第三个空格之后而不是第二个
我是 Bash 脚本的新手,一直在寻找正确的答案,以了解如何在第 n 次出现后使用 sed 替换任何内容(而不是替换第 n 次出现)。
例如,如果我想更改第二个空格之后的任何内容,我会输入以下句子:Today is a good day,结果是以下句子:Today is a friday
有什么想法吗?
【问题讨论】:
good 在第三个空格之后而不是第二个
你可以使用:
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
【讨论】:
[[:blank:]] 匹配空格或制表符。如果没有-r,我们需要转义括号以捕获组。
为什么不直接使用awk
echo "Today is a good day" | awk '{print $1,$2,"a friday"}'
Today is a friday
这将保留前两个字段,并替换该行的其余部分。
【讨论】:
我会说
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 脚本中非常适合作为标记。 & 指的是该行的匹配部分。
【讨论】:
据我了解,如果您使用的是 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 版中。贝壳衍生物。
【讨论】: