107

我在使用本网站上提供的答案时遇到一些问题这个问题是关于用另外两行内容替换一个空行的sed命令如果Mac OS上的sed命令(对我来说是10.6.7)不同,就会出现这种情况。我不认为是这样,但我想知道这个网站上的其他人是否有不同的想法。

5个答案5

重置为默认值
115

OSX目前从2005年起就带有FreeBSD sed。以下大多数差异也适用于其他BSD sed版本。

OS X的sed用法-E类用于ERE和GNU sed用途-第页.-E类是的别名-第页在GNU sed中(在4.2中添加,直到4.3才记录)。FreeBSD和NetBSD的新版本都支持-E类-第页.OpenBSD sed仅支持-E类.

-i“适用于OS X的sed,但不适用于GNU sed。-我与GNU sed、最新版本的NetBSD、OpenBSD配合使用塞德,但不是OS X的sed。-i-e两者都可以使用,但在FreeBSD的情况下塞德使用备份原始文件-e(电子)附加到文件名(并且不需要向传递多个表达式塞德).

GNU sed解释如下转义序列\秒\t吨\n个\001\x01个\w个、和\b条.OS X的sed和POSIX sed仅解释\n个(但不在的替换部分).

GNU sed解释\|\+、和\?在BRE中,但OS X的sed和POSIX sed没有。\(\)\{、和\}是POSIX BRE。

GNU sed允许省略;或换行符}但OSX的sed没有。

(插入),(追加),以及c(c)在OSX的sed和POSIX sed中,(change)后面必须跟一个反斜杠和换行符,但在GNU sed中不能跟。GNU sed在插入的文本后添加了一个缺少的换行符,或c(c)但OS X的sed没有。例如塞德1ia是GNU的替代品sed$“1i\\na\n”.

例如打印f a | sed-n p在OS X的sed中添加了一个换行符,但在GNU sed中没有。

OS X的sed不支持(区分大小写)或M(M)(多行)修改器。FreeBSD sed支持的更新版本.

OS X的sed不支持-秒(--分开),-u个(--无缓冲的),或-z(z)(--空数据).

GNU sed不支持的一个BSD选项是-一个,这使得w个附加到文件而不是截断文件。

不适用于OS X的sed的GNU sed命令示例:

sed/pattern/,+2d#类似“sed”/pattern/{N;N;d;}'`sed-n 0~3p#类似`awk NR%3==0`sed/pattern/Q#类似“awk”/pattern/{退出}1'`或'sed-n'/pattern/,$!p’`sed的/\b./\u&/g'#\u将下一个字符转换为大写sed的/^/\l&/'#\l将下一个字符转换为小写sed-i“1ecat file_to_prepend”file#e执行shell命令sed-n l0#0禁用包装
8
  • 11
    -i-e在OSX上不起作用。它插入-e(电子)作为后缀。 2016年1月26日21:07
  • 5
    @是的,在OS X版本中-我总是需要后缀,即使是空字符串也是如此-i“-e应该有效。 2016年9月9日15:13
  • 5
    这句话“-i-e两者都适用。“在你的回答中表明有一个跨平台的解决方案。显然没有。 2017年1月27日11:16
  • 1
    我已经有一段时间没有解决这个问题了(在这里寻找类似问题的解决方案);但在某一点上,我相信我能够通过明确有效载荷来获得这个工作的跨平台:sed-i=“”。。。 2019年4月26日21:09
  • 1
    值得注意的是,GNU sed很容易通过自制程序安装在macOS上brew安装gnu-sed然后可以调用为gsed公司.
    – 吹气器
    2022年6月13日10:36
58

在unix变体之间,shell实用程序的行为确实存在细微差异。有很多unix(通用)变体,带有复杂的 历史。有标准化工作例如POSIX公司标准及其超集单一UNIX规范。现在大多数系统都实现POSIX:2001,也称为单一UNIX规范版本3,有微小偏差和许多扩展。Single Unix规范不是教程,但如果您已经了解命令的作用,那么版本3是可读的。您可以查阅它以了解某些功能是标准的还是特定系统的扩展。

大多数unix用户使用Linux,并且没有使用任何其他变体。Linux附带GNU(全球导航单元)实用程序,通常对标准有许多扩展。因此,您会发现有很多代码可以在Linux上运行,但不能在其他unice上运行,因为它依赖于这些扩展。

关于sed,请咨询sed单一Unix规范对于每个系统应该支持的最小值系统上的手册页实现所支持的内容,以及基于GNU的手册为大多数人所用。

GNU-sed中的一个非标准扩展是支持同时运行多个命令。例如,此GNU sed程序打印包含,但有所改变b条进入之内c(c)第一:

sed-ne“/a/{s/b/c/g;p}”

{}实际上是单独的命令,因此为了实现完全的可移植性,您需要在单独的行(在文件中)或单独的行中指定它们-e(电子)参数(在命令行上)。之后缺少命令分隔符{以及;作为命令分隔符是常见的扩展。以前缺少命令分隔符}是一个不太常见的扩展。这符合标准:

sed-n-e’/a/{’-e’s/b/c/g’-e p-e’}’

这是非标准的,但被普遍接受:

sed-ne'/a/{s/b/c/g;p;}'

另一个非标准但常见的扩展是使用\n个表示a中的换行符替换文本(在regexp中使用是标准的)。可移植的方法是在sed脚本中包含反斜杠换行。另一个常见的扩展是\+\?\|在regexp中,表示一个或多个,最多一个和交替;可移植的基本正则表达式这些都不要。例如,第一个命令是用换行符替换连续的空格序列的一种不可移植的方法;第二个命令是符合标准的等效命令。

sed-e的/\+/\n/'sed-e的/*/\/'
2
  • 请注意,在所有关于GNU扩展的情况下,它的使用都是非标准的。GNU(全球导航单元)塞德它本身是兼容的,因为它做了标准允许的事情(但不是必需的,未指定的)。在某些情况下,它不符合要求,并且使用POSIXLY_CORRECT公司在环境中可以有所帮助。喜欢与s/[\n]//g必须消除齿隙和n个字符,但删除换行符。或其行为N个命令。 2017年7月23日8:01
  • sed-ne'/a/{s/b/c/g;p;}'是自2016年版标准以来的标准。它总是便携式的。请参见austingroupbugs.net/view.php?id=944&nbn=7 2017年7月23日8:04
12

我发现在Linux和Mac上使用相同脚本的最佳方法是:

sed-i.bak-e's/foo/bar/'--“${TARGET}”&&rm--“${TARGET}.bak”
1
  • 或者使用珍珠在哪里-我来自。perl-Tpi-e's/foo/bar/'--“$TARGET” 2017年7月23日8:16
4

此命令

sed’s/123\(4\+\)5/\1/g’

在Linux上工作,需要更改为

sed-E’s/123(4+)5/\1/g’

在我的Mac上工作。

所以,在Mac上,你不应该避开括号、星号和加号。您还需要添加-E类标志。

0

另一个不同之处在于Mac/BSD标准,它可以提供错误:非法的字节序列如果尝试处理LANG或LC_CTYPE设置为UTF-8的二进制文件。逗号分隔符不会给出错误。

如果在Mac/BSD上遇到该错误,可以尝试以下操作之一:

LC_CTYPE=Csed。。。LC_ALL=基于。。。LANG=Csed。。。

你必须登录来回答这个问题。

不是你想要的答案吗?浏览标记的其他问题.