bash - sed 使用 : expected context address

标签 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": 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/

相关文章:

bash - 将段错误消息从 C++ 程序重定向到文件

linux - 使用 Bash 删除特定标签

linux - 如何删除 .CSV 文件中第二次出现的模式后的其余记录

Bash - 仅使用 awk 打印矩阵的某些部分

node.js - Bower:安装后 "command not found"

linux - 使用 sed 命令更新配置文件的键值时出现问题

bash - 使用 sed 删除文件中的括号

c - 如何使用命令中的参数运行 execlp

轮询 : How to detect if client hangs up 的 C 套接字编程

c++ - Gnu Make 的递归性和 friend