在OS X上使用sed进行就地编辑

时间:2011-09-27 17:37:19

标签: macos file-io sed in-place

我想在OS X上使用sed编辑文件。我正在使用以下命令:

sed 's/oldword/newword/' file.txt

输出发送到终端。 file.txt 未修改。使用以下命令将更改保存到 file2.txt

sed 's/oldword/newword/' file1.txt > file2.txt

但是我不想要另一个文件。我只想编辑 file1.txt 。我怎么能这样做?

我尝试过-i标志。这会导致以下错误:

sed: 1: "file1.txt": invalid command code f

7 个答案:

答案 0 :(得分:231)

您可以正确使用-i标志,为其提供后缀以添加到备份文件中。扩展你的例子:

sed -i.bu 's/oldword/newword/' file1.txt

将为您提供两个文件:一个文件名为file1.txt,其中包含替换文件,另一个文件名为file1.txt.bu,其中包含原始内容。

轻度危险

如果要破坏性地覆盖原始文件,请使用以下内容:

sed -i '' 's/oldword/newword/' file1.txt
      ^ note the space

由于行解析的方式,选项标志与其参数之间需要一个空格,因为参数为零长度。

除了可能摧毁你的原件之外,我不知道以这种方式欺骗sed还有任何进一步的危险。然而,应该注意的是,如果sed的这个调用是脚本的一部分,那么Unix Way™(IMHO)将非破坏性地使用sed,测试它是否干净地退出,并且只有这样才能删除无关的文件。

答案 1 :(得分:15)

我与MacOS有类似的问题

sed -i '' 's/oldword/newword/' file1.txt

不起作用,但是

sed -i"any_symbol" 's/oldword/newword/' file1.txt

效果很好。

答案 2 :(得分:6)

-i 标志可能对您不起作用,因为您遵循了 GNU sed 的示例,而 macOS 使用 BSD sed 并且它们的语法略有不同。

所有其他答案都告诉您如何更正语法以使用 BSD sed。另一种方法是在您的 macOS 上安装 GNU sed:

brew install gsed

然后使用它代替 macOS 附带的 sed 版本(注意 g 前缀),例如:

gsed -i 's/oldword/newword/' file1.txt

如果您希望 GNU sed 命令始终可移植到您的 macOS,您可以将“gnubin”目录添加到您的路径中,方法是在您的 .bashrc/.zshrc 文件中添加类似内容(运行 { {1}} 以了解您到底需要做什么):

brew info gsed

从那时起,GNU sed 将成为您的默认 sed,您只需运行:

export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"

答案 3 :(得分:3)

您可以使用-i''--in-place)作为已建议的sed。请参阅:The -i in-place argument,但请注意-i选项是非标准的FreeBSD扩展,可能在其他操作系统上不可用。其次是sed is a Stream EDitor, not a file editor


替代方法是在Vim Ex模式下使用内置替换,例如:

$ ex +%s/foo/bar/g -scwq file.txt

和多个文件:

$ ex +'bufdo!%s/foo/bar/g' -scxa *.*

要以递归方式编辑所有文件,如果shell支持,则可以使用**/*.*(由shopt -s globstar启用)。


另一种方法是使用gawk及其新的"inplace" extension,例如:

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1

答案 4 :(得分:3)

您可以使用:

sed -i -e 's/<string-to-find>/<string-to-replace>/' <your-file-path>

示例:

sed -i -e 's/Hello/Bye/' file.txt

这在 Mac 中完美无缺。

答案 5 :(得分:2)

sed -i -- "s/https/http/g" file.txt

答案 6 :(得分:1)

这将创建备份文件。例如。 sed -i -e 's/hello/hello world/' testfile对我来说,在同一目录中创建一个备份文件testfile-e。