我在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”:预期的上下文地址
它出了什么问题?当我使用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
答案 0 :(得分:8)
它适用于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
答案 1 :(得分:4)
Mac OS X使用BSD sed
而非GNU sed
。
当您在Mac OS X sed
中使用GNU sed
扩展名时,会得到不同的结果或失败。
经典地,sed
不支持数字偏移,向前或向后。您需要修改脚本才能在Mac OS X上运行。
这适用于给定的数据,但fish
的使用是可疑的:
sed '/dog/,/your fish/s/^/# /g' pets.txt