为什么“sed -n -i"删除现有文件内容? [英] Why does "sed -n -i" delete existing file contents?

查看:51
本文介绍了为什么“sed -n -i"删除现有文件内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Running Fedora 25 server edition. sed --version gives me sed (GNU sed) 4.2.2 along with the usual copyright and contact info. I've create a text file sudo vi ./potential_sed_bug. Vi shows the contents of this file (with :set list enabled) as:

don't$
delete$
me$
please$

然后我运行以下命令:

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

在我们讨论结果之前;这是 sed 手册页所说的:

Before we discuss the results; here is what the sed man page says:

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

-n, --quiet, --silent suppress automatic printing of pattern space

-i[后缀], --in-place[=后缀]就地编辑文件(如果提供扩展名则进行备份).默认操作模式是断开符号链接和硬链接.这可以通过 --follow-symlinks 和 --copy 进行更改.

-i[SUFFIX], --in-place[=SUFFIX] edit files in place (makes backup if extension supplied). The default operation mode is to break symbolic and hard links. This can be changed with --follow-symlinks and --copy.

我还查看了 其他 sed 命令参考 以了解如何附加 sed.根据我对我所做研究的理解;生成的文件内容应该是:

I've also looked other sed command references to learn how to append with sed. Based on my understanding from the research I've done; the resulting file content should be:

don't
delete
me
please
testing

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

However, running sudo cat ./potential_sed_bug gives me the following output:

testing

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

In light of this discrepancy, is my understanding of the command I ran incorrect or is there a bug with sed/the environment?

推荐答案

tl;dr

  • 不要将 -n-i 一起使用:除非您在 sed 脚本中使用显式输出命令,否则什么都不会写入您的文件.

  • Don't use -n with -i: unless you use explicit output commands in your sed script, nothing will be written to your file.

使用 -i 不会产生 stdout(终端)输出,因此您无需执行任何额外操作即可让您的命令安静下来.

Using -i produces no stdout (terminal) output, so there's nothing extra you need to do to make your command quiet.

默认情况下,sed 自动将(可能被修改的)输入行打印到其输出目标是什么,无论是隐含的还是明确指定的:默认情况下,到 stdout(终端,除非重定向);使用 -i,到一个 临时文件,最终替换输入文件.

By default, sed automatically prints the (possibly modified) input lines to whatever its output target is, whether implied or explicitly specified: by default, to stdout (the terminal, unless redirected); with -i, to a temporary file that ultimately replaces the input file.

两种情况下,-n 抑制这种自动打印,因此 - 除非您使用显式输出函数,例如 p 或者,在你的情况下, a - nothing 被打印到标准输出/写入临时文件.

In both cases, -n suppresses this automatic printing, so that - unless you use explicit output functions such as p or, in your case, a - nothing gets printed to stdout / written to the temporary file.

  • 请注意,自动打印适用于所谓的模式空间,也就是(可能修改过的)输入所在的位置;paic 等显式输出函数打印到模式空间(用于潜在的后续修改),它们直接打印到目标流/文件,这就是为什么 a\testing 能够产生输出,尽管使用-n.
  • Note that the automatic printing applies to the so-called pattern space, which is where the (possibly modified) input is held; explicit output functions such as p, a, i and c do not print to the pattern space (for potential subsequent modification), they print directly to the target stream / file, which is why a\testing was able to produce output, despite the use of -n.

注意,使用 -ised 的隐式打印/显式输出命令打印到临时文件,而不是也打印到标准输出,因此使用 -i 的命令对于标准输出(终端)输出来说总是安静的 - 您不需要做任何额外的事情.

Note that with -i, sed's implicit printing / explicit output commands only print to the temporary file, and not also to stdout, so a command using -i is invariably quiet with respect to stdout (terminal) output - there's nothing extra you need to do.

举一个具体的例子(GNU sed 语法).

To give a concrete example (GNU sed syntax).

因为 -i 的使用是问题的附带条件,所以为了简单起见,我省略了它.请注意,-i 首先打印到临时文件,该文件在完成时替换原始文件.这伴随着陷阱,特别是符号链接的潜在破坏;请参阅我的这个答案的下半部分.

Since the use of -i is incidental to the question, I've omitted it for simplicity. Note that -i prints to a temporary file first, which, on completion, replaces the original. This comes with pitfalls, notably the potential destruction of symlinks; see the lower half of this answer of mine.

# 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

这篇关于为什么“sed -n -i"删除现有文件内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆