我在 macOS 上使用 sed
命令并使用以下文本:
$ cat pets.txt
This is my cat
my cat's name is betty
This is your dog
your dog's name is frank
This is your fish
your fish's name is george
This is my goat
my goat's name is adam
当我运行 BSD sed
时,它显示错误:
$ sed '/dog/,+3s/^/# /g' pets.txt
sed: 1: "/dog/,+3s/^/# /g": expected context address
这是怎么回事?当我使用 gsed
(GNU sed) 时,它运行良好:
This is my cat
my cat's name is betty
# This is your dog
# your dog's name is frank
# This is your fish
# your fish's name is george
This is my goat
my goat's name is adam
最佳答案
它适用于 GNU sed,因为您正在利用 GNU 项目添加到 sed 的功能,该功能以前不存在于程序中(并且在非 GNU 版本中仍然不存在)。
您可以在非 GNU sed 中使用类似这样的方法获得相同的结果:
sed -E '/dog/{N;N;N;s/(^|\n)/&# /g;}' pets.txt
也就是说,一旦我们看到“dog”,也拉入接下来的三行。然后在行首 (^
) 和所有换行符 (\n
) 之后添加一个 #
+ 空格。为了能够在单个正则表达式中进行搜索和替换,我们需要启用扩展的正则表达式,这就是 -E
所做的。没有它,我们可以用两个 s
命令来完成,一个用于行首,一个用于换行:
sed '/dog/{N;N;N;s/^/# /;s/\n/&# /g;}' pets.txt
如果您正在寻找另一种方法在不安装 GNU coreutils 的情况下在普通 Mac 上执行此操作,您可能需要使用其他实用程序,例如 awk:
awk '/dog/ {l=3}; (l-- > 0) {$0="# "$0} 1' pets.txt
或 perl(与 awk 版本的想法相同,只是语法不同):
perl -pe '$l=3 if /dog/; s/^/# / if $l-- > 0;' pets.txt
关于bash - sed 使用 : expected context address,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26124650/