sed命令与-i选项在Mac上失败,但在Linux上工作
我已经成功地使用下面的sed
命令在Linux中search/replace文本:
sed -i 's/old_link/new_link/g' *
但是,当我在我的Mac OS X上尝试它时,我得到:
“命令c期望\后跟文本”
我以为我的Mac运行一个正常的BASH shell。 这是怎么回事?
编辑:
根据@High Performance的说法,这是由于Mac sed
具有不同的(BSD)风格,所以我的问题是如何在BSD sed
复制这个命令?
编辑:
这是一个实际的例子,导致这个:
sed -i 's/hello/gbye/g' *
如果使用-i选项,则需要为备份提供扩展名。
如果你有:
File1.txt File2.cfg
命令:
sed -i '.original' 's/old_link/new_link/g' *
创build2个备份文件,如:
File1.txt.original File2.cfg.original
没有可移植的方法来避免制作备份文件,因为不可能find适用于所有情况的sed命令组合:
-
sed -i -e ...
– 在OS X上不起作用,因为它会创build-e
备份 -
sed -i'' -e ...
– 在OS X 10.6上不起作用,但在10.9+上工作 -
sed -i '' -e ...
– 不能在GNU上工作
当您使用-i时,我相信OS X是需要备份文件的扩展名。 尝试:
sed -i .bak 's/hello/gbye/g' *
使用GNU sed
扩展是可选的 。
这适用于sed的GNU和BSD版本:
sed -i'' -e 's/old_link/new_link/g' *
或备份:
sed -i'.bak' -e 's/old_link/new_link/g' *
请注意缺less-i
选项后的空间! (GNU sed必备)
或者,您可以在Mac中安装sed的GNU版本(称为gsed),并使用标准的Linux语法来使用它。
为此,通过运行sudo port install gsed
来安装使用端口(如果没有,请在http://www.macports.org/上获取)。; 然后,你可以运行sed -i 's/old_link/new_link/g' *
你的Mac确实运行了一个BASH shell,但是这更多的是你正在处理的sed实现的问题。 在Mac上,sed来自BSD,与典型的Linux机器上的sed有细微的差别。 我build议你的man sed
。
Sinetris的答案是正确的,但我用find
命令来更具体地说明我想更改的文件。 一般来说,这应该工作(在osx /bin/bash
上testing):
find . -name "*.smth" -exec sed -i '' 's/text1/text2/g' {} \;
一般情况下,在复杂项目中使用sed
而不find
效率较低。
在Mac中有相同的问题,并用brew
解决:
brew install gnu-sed
并用作
gsed SED_COMMAND
你可以设置sed
作为别名gsed
(如果你想):
alias sed=gsed
sed -ie 's/old_link/new_link/g' *
适用于BSD和Linux
正如其他答案所指出的那样,没有办法在没有备份文件的情况下跨OS X和Linux使用sed。 所以,我使用这个ruby单线程来做到这一点:
ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml
在我的情况下,我需要从一个rake
任务(即在一个Ruby脚本中)调用它,所以我使用了这个额外的引用级别:
sh %q{ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml}
以下是如何将环境variables应用于模板文件(无需备份)。
1.用{{FOO}}创build模板,以便以后replace。
echo "Hello {{FOO}}" > foo.conf.tmpl
2.用FOOvariablesreplace{{FOO}}并输出到新的foo.conf文件
FOO="world" && sed -e "s/{{FOO}}/$FOO/g" foo.conf.tmpl > foo.conf
同时使用macOS 10.12.4和Ubuntu 14.04.5