带有 -i 选项的 sed 命令在 Mac 上失败,但适用于 Linux
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4247068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
sed command with -i option failing on Mac, but works on Linux
提问by Yarin
I've successfully used the following sed
command to search/replace text in Linux:
我已成功使用以下sed
命令在 Linux 中搜索/替换文本:
sed -i 's/old_link/new_link/g' *
However, when I try it on my Mac OS X, I get:
但是,当我在 Mac OS X 上尝试时,我得到:
"command c expects \ followed by text"
“命令 c 需要 \ 后跟文本”
I thought my Mac runs a normal BASH shell. What's up?
我以为我的 Mac 运行的是普通的 BASH shell。这是怎么回事?
EDIT:
编辑:
According to @High Performance, this is due to Mac sed
being of a different (BSD) flavor, so my question would therefore be how do I replicate this command in BSD sed
?
根据@High Performance,这是由于 Macsed
具有不同的 (BSD) 风格,因此我的问题是如何在 BSD 中复制此命令sed
?
EDIT:
编辑:
Here is an actual example that causes this:
这是导致这种情况的实际示例:
sed -i 's/hello/gbye/g' *
采纳答案by Sinetris
If you use the -i
option you need to provide an extension for your backups.
如果使用该-i
选项,则需要为备份提供扩展名。
If you have:
如果你有:
File1.txt
File2.cfg
The command (note the lack of space between -i
and ''
and the -e
to make it work on new versions of Mac and on GNU):
该命令(注意缺乏之间的空间-i
,并''
与-e
以使其在Mac和在GNU新版本一起使用):
sed -i'.original' -e 's/old_link/new_link/g' *
Create 2 backup files like:
创建 2 个备份文件,例如:
File1.txt.original
File2.cfg.original
There is no portable way to avoid making backup files because it is impossible to find a mix of sed commands that works on all cases:
没有可移植的方法来避免制作备份文件,因为不可能找到适用于所有情况的 sed 命令组合:
sed -i -e ...
- does not work on OS X as it creates-e
backupssed -i'' -e ...
- does not work on OS X 10.6 but works on 10.9+sed -i '' -e ...
- not working on GNU
sed -i -e ...
- 不适用于 OS X,因为它会创建-e
备份sed -i'' -e ...
- 不适用于 OS X 10.6 但适用于 10.9+sed -i '' -e ...
- 不在 GNU 上工作
NoteGiven that there isn't a sed command working on all platforms, you can try to use another command to achieve the same result.
注意鉴于没有一个 sed 命令适用于所有平台,您可以尝试使用另一个命令来获得相同的结果。
E.g., perl -i -pe's/old_link/new_link/g' *
例如, perl -i -pe's/old_link/new_link/g' *
回答by High Performance Mark
Your Mac does indeed run a BASH shell, but this is more a question of which implementation of sed you are dealing with. On a Mac sed comes from BSD and is subtly different from the sed you might find on a typical Linux box. I suggest you man sed
.
您的 Mac 确实运行了 BASH shell,但这更多是您正在处理的 sed 实现的问题。在 Mac 上,sed 来自 BSD,与您可能在典型的 Linux 机器上找到的 sed 略有不同。我建议你man sed
。
回答by Paused until further notice.
I believe on OS X when you use -i an extension for the backup files is required. Try:
我相信在 OS X 上使用 -i 时需要备份文件的扩展名。尝试:
sed -i .bak 's/hello/gbye/g' *
Using GNU sed
the extension is optional.
使用 GNU 时sed
,扩展名是可选的。
回答by Ohad Kravchick
Or, you can install the GNU version of sed in your Mac, called gsed, and use it using the standard Linux syntax.
或者,您可以在 Mac 中安装 sed 的 GNU 版本,称为 gsed,并使用标准 Linux 语法使用它。
For that, install gsed
using ports (if you don't have it, get it at http://www.macports.org/) by running sudo port install gsed
. Then, you can run sed -i 's/old_link/new_link/g' *
为此,安装gsed
使用的端口(如果你没有它,得到它在http://www.macports.org/)运行sudo port install gsed
。然后,你可以运行sed -i 's/old_link/new_link/g' *
回答by Lucas
Sinetris' answer is right, but I use this with find
command to be more specific about what files I want to change. In general this should work (tested on osx /bin/bash
):
Sinetris 的回答是正确的,但我将它与find
命令一起使用以更具体地说明我想要更改的文件。一般来说,这应该有效(在 osx 上测试/bin/bash
):
find . -name "*.smth" -exec sed -i '' 's/text1/text2/g' {} \;
In general when using sed
without find
in complex projects is less efficient.
一般来说,在复杂项目中使用sed
without时find
效率较低。
回答by chipiik
This works with both GNU and BSD versions of sed:
这适用于 sed 的 GNU 和 BSD 版本:
sed -i'' -e 's/old_link/new_link/g' *
or with backup:
或有备份:
sed -i'.bak' -e 's/old_link/new_link/g' *
Note missing space after -i
option! (Necessary for GNU sed)
注意-i
选项后缺少空格!(对于 GNU sed 是必需的)
回答by ashokrajar
sed -ie 's/old_link/new_link/g' *
Works on both BSD & Linux
适用于 BSD 和 Linux
回答by Sruthi Poddutur
Had the same problem in Mac and solved it with brew
:
在 Mac 中遇到了同样的问题并使用以下方法解决了它brew
:
brew install gnu-sed
and use as
并用作
gsed SED_COMMAND
you can set as well set sed
as alias to gsed
(if you want):
您可以将sed
别名设置为gsed
(如果需要):
alias sed=gsed
回答by Dan Kohn
As the other answers indicate, there is not a way to use sed portably across OS X and Linux without making backup files. So, I instead used this Ruby one-liner to do so:
正如其他答案所表明的那样,没有一种方法可以在不制作备份文件的情况下在 OS X 和 Linux 上便携地使用 sed。所以,我改为使用这个 Ruby one-liner 来做到这一点:
ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml
In my case, I needed to call it from a rake
task (i.e., inside a Ruby script), so I used this additional level of quoting:
就我而言,我需要从rake
任务(即在 Ruby 脚本中)调用它,所以我使用了这个额外的引用级别:
sh %q{ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml}
回答by katopz
Here's how to apply environment variables to template file (no backup need).
以下是如何将环境变量应用于模板文件(无需备份)。
1. Create template with {{FOO}} for later replace.
1. 用 {{FOO}} 创建模板以备后用。
echo "Hello {{FOO}}" > foo.conf.tmpl
2. Replace {{FOO}} with FOO variable and output to new foo.conf file
2. 将 {{FOO}} 替换为 FOO 变量并输出到新的 foo.conf 文件
FOO="world" && sed -e "s/{{FOO}}/$FOO/g" foo.conf.tmpl > foo.conf
Working both macOS 10.12.4and Ubuntu 14.04.5
适用于macOS 10.12.4和Ubuntu 14.04.5