为什么 "sed -n -i" 删除现有文件内容?
Why does "sed -n -i" delete existing file contents?
运行 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
suppress automatic printing of pattern space
和
-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.
我还查看了 other sed command references 以了解如何使用 sed 追加。根据我所做的研究的理解;生成的文件内容应为:
don't
delete
me
please
testing
但是,运行ning sudo cat ./potential_sed_bug
给我以下输出:
testing
鉴于这种差异,是我对命令 I 运行 的理解不正确还是 sed/the 环境存在错误?
tl;dr
不要将 -n
与 -i
一起使用:除非您在 sed
脚本中使用明确的输出命令,否则不会向您的文件写入任何内容。
使用 -i
会产生 no stdout(终端)输出,因此您无需执行任何额外操作即可使命令安静。
默认情况下,sed
自动将(可能修改过的)输入行打印到其输出目标,无论是隐含的还是明确指定的:默认情况下,到 stdout (终端,除非重定向);使用 -i
,到最终替换输入文件的 临时文件 。
在两种情况下,-n
抑制这种自动打印,所以-除非你使用明确的输出功能,如p
或者,在您的情况下,a
- nothing 被打印到标准输出/写入临时文件。
- 请注意,自动打印适用于所谓的 模式 space,这是(可能已修改的)input举行;
p
、a
、i
和 c
等显式输出函数 而不是 打印到模式 space (对于潜在的后续修改),它们将 直接打印到目标流/文件 ,这就是为什么 a\testing
能够产生输出,尽管使用了 -n
。
请注意,使用 -i
、sed
的隐式打印/显式输出命令 仅 打印到临时文件,而不是标准输出,因此使用 -i
的命令相对于 stdout(终端)输出总是安静的 - 您不需要做任何额外的事情。
举个具体的例子(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
运行 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 suppress automatic printing of pattern space
和
-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.
我还查看了 other sed command references 以了解如何使用 sed 追加。根据我所做的研究的理解;生成的文件内容应为:
don't
delete
me
please
testing
但是,运行ning sudo cat ./potential_sed_bug
给我以下输出:
testing
鉴于这种差异,是我对命令 I 运行 的理解不正确还是 sed/the 环境存在错误?
tl;dr
不要将
-n
与-i
一起使用:除非您在sed
脚本中使用明确的输出命令,否则不会向您的文件写入任何内容。使用
-i
会产生 no stdout(终端)输出,因此您无需执行任何额外操作即可使命令安静。
默认情况下,sed
自动将(可能修改过的)输入行打印到其输出目标,无论是隐含的还是明确指定的:默认情况下,到 stdout (终端,除非重定向);使用 -i
,到最终替换输入文件的 临时文件 。
在两种情况下,-n
抑制这种自动打印,所以-除非你使用明确的输出功能,如p
或者,在您的情况下,a
- nothing 被打印到标准输出/写入临时文件。
- 请注意,自动打印适用于所谓的 模式 space,这是(可能已修改的)input举行;
p
、a
、i
和c
等显式输出函数 而不是 打印到模式 space (对于潜在的后续修改),它们将 直接打印到目标流/文件 ,这就是为什么a\testing
能够产生输出,尽管使用了-n
。
请注意,使用 -i
、sed
的隐式打印/显式输出命令 仅 打印到临时文件,而不是标准输出,因此使用 -i
的命令相对于 stdout(终端)输出总是安静的 - 您不需要做任何额外的事情。
举个具体的例子(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