我已经成功地使用下面的sed命令来搜索/替换Linux中的文本:

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' *

当前回答

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

find . -name "*.smth" -exec sed -i '' 's/text1/text2/g' {} \;

一般来说,在复杂的项目中使用不带find的sed效率较低。

其他回答

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

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
}

用法:

$(replace_in_file 's,MASTER_HOST.*,MASTER_HOST='"$MASTER_IP"',' "./mysql/.env")

地点:

,是delimeter

的年代,MASTER_HOST。*,MASTER_HOST=' ' $MASTER_IP ','是模式

”。/ mysql /。Env "是文件的路径

下面是如何将环境变量应用到模板文件(不需要备份)。

1. 用{{FOO}}创建模板供以后替换。

echo "Hello {{FOO}}" > foo.conf.tmpl

2. 将{{FOO}}替换为FOO变量并输出到新的FOO .conf文件

FOO="world" && sed -e "s/{{FOO}}/$FOO/g" foo.conf.tmpl > foo.conf

支持macOS 10.12.4和Ubuntu 14.04.5

正如其他答案所表明的那样,如果不创建备份文件,就无法在OS X和Linux之间可移植地使用sed。所以,我转而使用Ruby的一行代码来实现:

ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml

在我的例子中,我需要从rake任务中调用它(即在Ruby脚本中),所以我使用了以下附加级别的引用:

sh %q{ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml}

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

brew install gnu-sed

使用as

gsed SED_COMMAND

你也可以将sed作为别名设置为gsed(如果你想):

alias sed=gsed

下面是bash脚本中的一个选项:

#!/bin/bash

GO_OS=${GO_OS:-"linux"}

function detect_os {
    # Detect the OS name
    case "$(uname -s)" in
      Darwin)
        host_os=darwin
        ;;
      Linux)
        host_os=linux
        ;;
      *)
        echo "Unsupported host OS. Must be Linux or Mac OS X." >&2
        exit 1
        ;;
    esac

   GO_OS="${host_os}"
}

detect_os

if [ "${GO_OS}" == "darwin" ]; then
    sed -i '' -e ...
else
    sed -i -e ...
fi