为什么“sed -n -i”删除现有的文件内容?
运行Fedora 25服务器版。 sed --version
给我sed (GNU sed) 4.2.2
以及通常的版权和联系信息。我已经创建了一个文本文件sudo vi ./potential_sed_bug
。 VI显示该文件的内容(与:set list
启用)为:为什么“sed -n -i”删除现有的文件内容?
don't$
delete$
me$
please$
我然后运行以下命令:
sudo sed -n -i.bak /please/a\testing ./potential_sed_bug
在我们讨论的结果;这里是什么sed man page说:
-n,--quiet,--silent 抑制模式空间的自动打印
和
-i [后缀] - 就地编辑[=后缀] 编辑文件(如果提供了扩展名,则进行备份)。默认操作模式是中断符号链接和硬链接。这可以通过--follow-symlinks和--copy来改变。
我也看了other sed command references了解如何追加sed。根据我对我所做的研究的理解;生成的文件内容应该是:
don't
delete
me
please
testing
但是,运行sudo cat ./potential_sed_bug
给我下面的输出:
testing
在这种差异的光,是我,我跑不正确或命令的理解是有sed /环境有问题吗?
TL;博士
不要使用
-n
与-i
:除非你在sed
脚本中使用明确的输出命令,什么都不会被写入文件。使用
-i
产生没有标准输出(终端)的输出,所以没有什么多余的,你需要做的,使你的命令安静。
默认情况下,sed
自动打印(可能被修改)输入线到任何其输出目标是,不论是隐含的或显式指定:通过默认,向标准输出(终端,除非重定向) ;与-i
,到最终替换输入文件的临时文件。
在两种案件,-n
抑制这个自动打印,这样 - 除非你使用显式输出功能,如p
或者,你的情况,a
- 什么被打印到stdout /写入临时文件。
- 注意,自动打印适用于所谓的图案空间,这是其中(可能被修改)输入被保持;明确的输出功能,例如
p
,a
,i
和c
做不打印到图案空间(潜在的后续修改),它们打印直接向目标流/文件,这就是为什么a\testing
能够产生输出,尽管使用-n
。
注意,与-i
,sed
的隐式印刷/显式输出指令仅打印到临时文件,而不是也到stdout,因此使用-i
一个命令是总是安静相对于标准输出(端子)输出 - 没有什么额外的你需要做的。
为了给出一个具体的例子(GNUsed
语法)。
由于使用-i
是偶然的问题,为简单起见,我省略了它。请注意,-i
首先打印到临时文件,其中,完成后,替换原来的。这与陷阱,尤其是符号链接的潜在破坏;看到我的this answer的下半部分。
# Print input (by default), and append literal 'testing' after
# lines that contain 'please'.
$ sed '/please/ a testing' <<<$'yes\nplease\nmore'
yes
please
testing
more
# Adding `-n` suppresses the default printing, so only `testing` is printed.
# Note that the sequence of processing is exactly the same as without `-n`:
# If and when a line with 'please' is found, 'testing' is appended *at that time*.
$ sed -n '/please/ a testing' <<<$'yes\nplease\nmore'
testing
# Adding an unconditional `p` (print) call undoes the effect of `-n`.
$ sed -n 'p; /please/ a testing' <<<$'yes\nplease\nmore'
yes
please
testing
more
@AMemberofDollars:这样做的缺点:处理的顺序没有改变,是的,临时文件首先被写入,只有在完成它取代原来的 - 请我的更新。 – mklement0
@stevesliva:我明白了,谢谢。我已经相应地更新了答案。 – mklement0
有趣的是,我一直认为'sed -e cmd1 | sed -e cmd2'相当于'sed -e cmd1 -e cmd2',但是如果由于某种原因你想要修改的内容是你正在追加的内容,那么这个区域实际上就是想要sed到sed的。我想'n'和'q'其他命令也会打破这种等价性。 – stevesliva