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


142

我想在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

2
尝试使用-i标志时,您使用的确切命令是什么?
eldarerathis 2011年

Answers:


281

您可以通过为-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非破坏性方式使用,测试其是否干净退出,然后才删除无关的文件。


没错,我在-i标志后省略了扩展名。-i''除了可能破坏原始文件(并且没有备份)以外,出于其他原因是否还很危险?
2011年

根据sed手册页的说明,如果设备上的磁盘空间不足,则可能会跨步破坏文件并导致输出结果错误。如果您在本地源代码控制sed -i ""下工作而没有备份,则大多数情况下(或git init && git add -A . && git commit -m 'backup'在以-i模式运行sed之前)应该没问题。
cfeduke 2014年

2
我发现轻度危险的位特别有用。+1
Andre

5
BSD sed要求-i标志后没有空格。因此,-i''有效,但-i ''无效。
Todd A. Jacobs 2015年

3
啊!BSD sed忽略了'\ n'字符而改为打印'n'!我只是要用Mac上的GNU sed替换BSD sed!
特里

20

我对MacOS也有类似的问题

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

不起作用,但是

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

效果很好。


现在反过来了。sed -i '' <file>有效但sed -i'' <file>不再有效
Zohaib Amanzai


4

您可以根据需要使用-i''--in-placesed。见:-i就地说法,但是请注意,-i选项是非标准的FreeBSD扩展和可能并不适用于其他操作系统。其次sedS tream ED管理员,而不是文件编辑器


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

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

对于多个文件:

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

要递归编辑所有文件,可以**/*.*在shell支持的情况下使用(由启用shopt -s globstar)。


另一种方法是使用gawk及其新的“ inplace”扩展,例如:

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

4

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


与Mac OS Catalina相同。分别传递-i和-e(不要同时传递-e!)会创建一个附加了-e的备份文件。
Daniel Kesner,

1

您可以使用:

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

例:

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

Mac中,此功能完美无缺。


2
这会在Mac OS Catalina中为我创建一个备份文件,并附加“ -e”。
Daniel Kesner,

对于macOS,这是错误的。请在此处查看“ man sed”页面。-i需要macOS的参数。由于您未指定文件名,因此使用-e,这将导致-e附加第二个文件。-e在macOS中不存在,而是-E。因此,macOS的正确命令是sed -i '' -E 's/Hello/Bye/' file.txt
Marc J. Schmidt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.