sed使用:预期的上下文地址

时间:2014-09-30 15:31:49

标签: bash sed gnu bsd

我在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

2 个答案:

答案 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