为什么“sed -n -i”会删除现有的文件内容?

时间:2017-03-07 01:14:52

标签: sed gnu-sed

运行Fedora 25服务器版。 sed --version向我sed (GNU sed) 4.2.2提供了通常的版权和联系信息。我创建了一个文本文件sudo vi ./potential_sed_bug。 Vi将此文件的内容(启用:set list)显示为:

don't$
delete$
me$
please$

然后我运行以下命令:

sudo sed -n -i.bak /please/a\testing ./potential_sed_bug

在我们讨论结果之前;这是sed man page所说的内容:

  

-n, - quiet, - silent   抑制模式空间的自动打印

  

-i [SUFFIX], - in-place [= SUFFIX]   编辑文件(如果提供扩展,则进行备份)。默认操作模式是打破符号和硬链接。这可以使用--follow-symlinks和--copy。

进行更改

我还看了other sed command references以了解如何使用sed追加。根据我对我所做研究的理解;生成的文件内容应为:

don't
delete
me
please
testing

但是,运行sudo cat ./potential_sed_bug会给我以下输出:

testing

鉴于这种差异,我对我运行的命令的理解不正确或是否有sed /环境的错误?

1 个答案:

答案 0 :(得分:3)

<强> TL;博士

  • 不要将-n-i一起使用:除非在sed脚本中使用显式输出命令,否则不会将任何内容写入您的文件。

    < / LI>
  • 使用-i生成 no stdout(终端)输出,因此您无需额外执行任何操作即可使命令保持安静。

默认情况下,sed会自动将(可能已修改的)输入行打印到其输出目标的任何位置,无论是暗示还是显式指定:默认情况下,输出到 stdout (终端,除非重定向);使用-i,最终替换输入文件的临时文件

两个情况下,-n 禁止此自动打印,因此 - 除非您使用显式输出函数,例如p或你的情况,a - 没有被打印到stdout /写入临时文件。

  • 请注意,自动打印适用于所谓的模式空间,这是(可能已修改的)输入所在的位置;明确的输出函数,例如paic 打印到模式空间(用于潜在的后续修改),它们将直接打印到目标流/文件,这就是a\testing能够产生输出的原因,尽管使用了-n

请注意,对于-ised的隐式打印/显式输出命令打印到临时文件,而不是打印到stdout,因此命令使用{对于stdout(终端)输出,{1}}总是很安静 - 你不需要做任何额外的事情。

举一个具体的例子( GNU -i语法)。

由于使用sed是附带的问题,为简单起见,我省略了它。请注意,-i首先打印到临时文件,完成后,替换原始文件。这带来了陷阱,特别是符号链接的潜在破坏;看到我this answer的下半部分。

-i