使用-i选项的sed命令在Mac上失败,但适用于Linux

Yar*_*rin 271 linux macos bash sed

我已成功使用以下sed命令在Linux中搜索/替换文本:

sed -i 's/old_link/new_link/g' *
Run Code Online (Sandbox Code Playgroud)

但是,当我在Mac OS X上试用它时,我得到:

"命令c期望\后跟文本"

我以为我的Mac运行普通的BASH shell.这是怎么回事?

编辑:

根据@High Performance,这是由于Mac sed具有不同的(BSD)风格,因此我的问题是如何在BSD中复制此命令sed

编辑:

以下是导致此问题的实际示例:

sed -i 's/hello/gbye/g' *
Run Code Online (Sandbox Code Playgroud)

Sin*_*ris 356

如果使用-i选项,则需要为备份提供扩展.

如果你有:

File1.txt
File2.cfg
Run Code Online (Sandbox Code Playgroud)

命令(注意和之间缺少空间-i以及使其适用于新版本的Mac和GNU):-i''

sed -i'.original' -e 's/old_link/new_link/g' *
Run Code Online (Sandbox Code Playgroud)

创建2个备份文件,如:

File1.txt.original
File2.cfg.original
Run Code Online (Sandbox Code Playgroud)

没有可移植的方法来避免制作备份文件,因为无法找到适用于所有情况的混合sed命令:

  • -e- 因为它创建sed -i -e ...备份而无法在OS X上运行
  • -e - 不适用于OS X 10.6,但适用于10.9+
  • sed -i'' -e ... - 没有在GNU上工作

注意鉴于没有sed命令在所有平台上运行,您可以尝试使用另一个命令来实现相同的结果

例如 sed -i '' -e ...

  • @lukmac至于`sed`可以告诉你,你DID提供了一个备份后缀.备份后缀是`s/old_link/new_link/g`.之后的下一个参数应该是编辑命令.因为它将命令解释为备份名称,所以它将第一个文件名作为编辑命令,但它们无效. (5认同)
  • 我遇到过同样的问题.谢谢你的解决方案.但是,当我尝试使用'man sed'来查找'-i'的描述时,没有任何关于使用-i''忽略备份的信息.这是我的第一个责任.第二,当错误"命令期望\后跟文本"出现时,为什么不直接告诉我们它期望选项'-i'的备份名称!! ?? 这样的事情到处发生:你得到一个错误,但不是为什么错误,然后你搜索手册,它没有解释它.然后你google它找到别人也有同样的问题.我的意思是,为什么不在手册中给出例子呢? (4认同)
  • `sed -i'' - e`似乎在Mac 10.14上无法正常工作 (3认同)
  • 这总是一个问题吗?Apple有没有办法用OSX创建一个解决方法/包GNU sed?或者,不能GNU sed支持`sed -i''-e ...`? (2认同)
  • `sed -i -- ...` 似乎工作正常。还提到@/sf/answers/3517151011/ (2认同)

Pau*_*ce. 57

当你使用-i时,我相信OS X 需要一个扩展备份文件.尝试:

sed -i .bak 's/hello/gbye/g' *
Run Code Online (Sandbox Code Playgroud)

使用GNU sed,扩展是可选的.


chi*_*iik 53

这适用于sed的GNU和BSD版本:

sed -i'' -e 's/old_link/new_link/g' *
Run Code Online (Sandbox Code Playgroud)

或备份:

sed -i'.bak' -e 's/old_link/new_link/g' *
Run Code Online (Sandbox Code Playgroud)

注意-i选项后缺少空格!(GNU sed必备)

  • 第一个不适用于OSX(我刚刚在10.6.8上测试过) (6认同)
  • 对于我在OS X(10.10.3)上,第一个创建了以-e为后缀的备份文件.不好.第二个是Ubuntu和OS X之间唯一对我有用的东西.虽然我不想要备份文件,所以我必须立即运行`rm`命令来删除它. (4认同)
  • 第一行应该用空格重写以在 10.10 上工作:`sed -i'' ...` => `sed -i '' ...` (2认同)
  • @DanielJomphe但是添加这个空间对GNU sed不起作用 (2认同)
  • 投了反对票,因为我在这件事上浪费了太多时间,但没有成功。(第一件事)。备份有效,但我想要没有,另一个答案中的“perl -i -pe”给出了这一点:) (2认同)

Sru*_*tur 30

在Mac中遇到同样的问题并解决了它brew:

brew install gnu-sed
Run Code Online (Sandbox Code Playgroud)

并用作

gsed SED_COMMAND
Run Code Online (Sandbox Code Playgroud)

您可以设置为sed别名gsed(如果需要):

alias sed=gsed
Run Code Online (Sandbox Code Playgroud)

  • 按照相应的 brew 页面中的建议,不要使用别名,而是将其添加到路径: PATH="$(brew --prefix)/opt/gnu-sed/libexec/gnubin:$PATH" (3认同)
  • 您为什么要给出准确的[相同答案](http://stackoverflow.com/questions/4247068/sed-command-with-i-option-failing-on-mac-but-works-on-linux/10304970#10304970 )作为[Ohad Kravchick](http://stackoverflow.com/users/455262/ohad-kravchick)? (2认同)
  • 像这样设置别名不是一个好主意 (2认同)
  • 由于我们都是懒惰的开发人员,请将此行添加到您的 `~/.zshrc` 或 bashrc 文件中: `export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"` 然后运行 `source ~/.zshrc` 更改为您选择的 rc 文件!然后运行“which sed”来检查它是否已更改。 (2认同)

Oha*_*ick 20

或者,您可以在Mac中安装GNU版本的sed,名为gsed,并使用标准Linux语法进行使用.

为此,请运行gsed使用端口(如果没有端口,请通过http://www.macports.org/获取)sudo port install gsed.然后,你可以运行sed -i 's/old_link/new_link/g' *

  • ..或者如果你使用自制软件,那么安装`gnu-sed` (22认同)

Hig*_*ark 8

你的Mac确实运行了一个BASH shell,但这更像是你正在处理的sed实现的问题.在Mac上,sed来自BSD,与您在典型Linux机器上可能找到的sed略有不同.我建议你man sed.

  • 大多数SO答案都埋藏在男人的某个地方,但那就是那些需要智能人士答案的忙碌人士 (18认同)
  • @Yarin - 不,如果我快速浏览一下man sed,那也不会告诉你任何事情.再试一次. (5认同)
  • 感谢你指出了BSD的问题 - 但是我非常喜欢文盲,只需要快速修复我的命令 - 快速浏览一下男人并没有告诉我任何事情 (3认同)

Luc*_*cas 8

Sinetris的答案是正确的,但我使用find命令来更具体地说明我想要更改的文件.一般来说这应该工作(在osx上测试/bin/bash):

find . -name "*.smth" -exec sed -i '' 's/text1/text2/g' {} \;
Run Code Online (Sandbox Code Playgroud)

通常,在sed没有find复杂项目的情况下使用效率较低.

  • @YeLiu:没有````,```在我尝试的时候被shell解释了 (2认同)

v.b*_*bak 7

我创建了一个函数来处理sedMacOS(在 MacOS 10.12 上测试)和其他操作系统之间的差异:

OS=`uname`
# $(replace_in_file pattern file)
function replace_in_file() {
    if [ "$OS" = 'Darwin' ]; then
        # for MacOS
        sed -i '' -e "$1" "$2"
    else
        # for Linux and Windows
        sed -i'' -e "$1" "$2"
    fi
}
Run Code Online (Sandbox Code Playgroud)

用法:

$(replace_in_file 's,MASTER_HOST.*,MASTER_HOST='"$MASTER_IP"',' "./mysql/.env")
Run Code Online (Sandbox Code Playgroud)

在哪里:

,是一个分隔符

's,MASTER_HOST.*,MASTER_HOST='"$MASTER_IP"','是模式

"./mysql/.env"是文件的路径


ame*_*ior 5

sed除了调用 sed with ,我做./bin/sed

这是我的包装脚本 ~/project/bin/sed

#!/bin/bash

if [[ "$OSTYPE" == "darwin"* ]]; then
  exec "gsed" "$@"
else
  exec "sed" "$@"
fi
Run Code Online (Sandbox Code Playgroud)

不要忘记chmod 755包装脚本。

  • 假设您已经在 Mac 上预先完成了“brew install gnu-sed” (2认同)