在 OS X 上使用“sed”和“find”命令时出错:“命令代码无效。”

问题描述 投票:0回答:7

当前客户端被迫使用 CVS,并且远程存储库的地址已更改。我能找到的在本地代码中更改远程地址的唯一方法是递归搜索和替换。

但是,使用 sed 命令我希望可以工作:

find ./ -type f -exec sed -i "s/192.168.20.1/new.domain.com/" {} \;

每个文件都出现错误:

sed: 1: ".//file/path ...": invalid command code .

我试图逃避 sed 匹配/替换中的句点,但这并不能解决任何问题。

bash macos sed find
7个回答
825
投票

如果您使用的是 OS X,这可能与 sed 命令无关。在 OSX 版本的

sed
上,
-i
选项需要一个
extension
参数,因此您的命令实际上被解析为
extension
参数,并且文件路径被解释为命令代码。

尝试显式添加

-e
参数并将
''
作为
-i
的参数:

find ./ -type f -exec sed -i '' -e "s/192.168.20.1/new.domain.com/" {} \;

参见这个


130
投票

在 OS X 上,没有什么可以帮助可怜的内置 sed 变得足够。解决办法是:

brew install gnu-sed

然后使用 gsed 而不是 sed,这将按预期工作。


68
投票

您只是忘记向

-i
提供参数。只需将
-i
更改为
-i ''

当然,这意味着您不希望您的文件被备份;否则请提供您选择的扩展名,例如

-i .bak


8
投票

只需向 -i 标志添加扩展即可。这基本上会使用原始文件创建一个备份文件。

sed -i.bakup  's/linenumber/number/' ~/.vimrc

sed 将执行而不会出现错误


3
投票

OP 的情况并非如此,但对我来说是这样,并且可以帮助其他人。

如果您使用

'
括起正则表达式,请仔细检查
'
字符。我正在从文字处理中复制并粘贴脚本,并将
'
粘贴为 bash 中的


2
投票

您的新域名可能包含

/
?如果是这样,请尝试在
/
中使用除
sed
之外的分隔符,例如
#
,

find ./ -type f -exec sed -i 's#192.168.20.1#new.domain.com#' {} \;

最好将

s///
用单引号而不是双引号括起来,以避免变量替换或任何其他意外行为


0
投票

要将此

find
命令转换为 macOS,我们需要为
-i
正确处理
sed
选项。它应该是这样的:

find ./ -type f -exec sed -i '' "s/192.168.20.1/new.domain.com/g" {} +

变更说明

  1. -i ''
    :macOS
    -i
    中的
    sed
    选项需要备份扩展。
    -i ''
    (空字符串)告诉它就地编辑文件而不创建备份。
  2. +
    +
    之后的
    {}
    告诉
    find
    一次将多个文件传递给
    sed
    ,这比在每个文件上单独运行
    sed
    更有效(可选,但对于较大的目录很有用) ).
  3. g
    :在
    g
    表达式 (
    sed
    ) 末尾添加
    s/192.168.20.1/new.domain.com/g
    ,以替换每行中所有出现的
    192.168.20.1
    ,而不仅仅是第一次出现。

现在应该可以按预期在 macOS 上运行。

© www.soinside.com 2019 - 2024. All rights reserved.