我试图使用以下sed
命令将目录中多个文件中的单词替换为其他内容:
sed -n -i 's/pattern/replacement/g' "dir"/*
我原以为我的文件中匹配的单词pattern
将被我的单词替换replacement
,但它并没有,相反,里面的所有文件dir
都被擦除了内容。
根据sed's
联机帮助页,-n
、--quiet
、--silent
抑制图案空间的自动打印。
根据我的理解,在sed
处理一行文本之前,sed
将它们首先放在pattern space
然后sed
应用给定的命令,例如替换命令s///
然后默认打印出结果文本。
我以为,通过使用-n
,我只是阻止sed
将任何文本打印到stdout
,但我想我错了,并且花费了我重要的文件,我忘记备份 T_T
答案1
sed
代表 ”s特雷姆编辑ed
itor”。它的流媒体版本是文件编辑器。
所以,就是sed
这样故意的要使用的,是它总是生成输出到标准输出。那是手册和手册中使用术语“打印”的方式规格。
-i
是一个非标准扩展用于编辑不存在于所有实现中的文件,sed
并且不保证在那些实现中表现相同做实施它。 (例如,在我的系统上,您的命令会生成错误,因为备份文件扩展名是必需的。即在我的系统上,我必须指定类似的内容sed -n -i savemybutt 's/pattern/replacement/g' "dir"/*
,然后在编辑之前将每个文件备份foo.txt
到foo.txt.savemybutt
。)
事实上,这-i
既是非标准的又是事后才想到的,这意味着您的实现文档中的标准术语sed
(我假设它是 GNU sed)从未改变过,因此它仍然使用术语“print”来表示“生成输出”中的一般意义。
换句话说:在sed
的标准操作模式下,唯一办法生成输出的方法是将其打印到标准输出。没有办法编辑文件。因此,在标准操作模式下,打印和输出是相同的。一旦你加入-i
其中,事情就会变得更加模糊,但是“打印”仍然意思是“生成输出”一般意义即使输出到文件,因为这就是“打印”的内容总是的意思。
这意图的-n
就是它仅有的生成您显式打印的输出,例如使用以下p
命令:
sed -n '/<body>/,/<\/body/p' < some_html_document.html
这将(粗略地)打印body
HTML 文档的元素。 (当然,这是一个愚蠢的例子。)
答案2
你的描述-n
似乎很到位。不过你似乎不太清楚-i
。
正常行为是输出到 stdout。所以“我认为,通过使用 -n,我只是阻止 sed 将任何文本打印到标准输出”意味着停止它的工作。
然后-i
改变行为以到位。但有些结果。
今后如何避免
下次测试时不带-i
.所以输出到标准输出:没有发生突变。 (函数式编程(无突变)比过程式编程更安全)。
除非测试失败,否则不要编写代码。 (您是否有任何导致问题的标准输出?)
答案3
根据man sed
-n, --quiet, --silent
suppress automatic printing of pattern space
这不是有用的方式sed
命令。你可以这样使用:
sed -n 's/pattern/replacement/p' "dir"/*
用于打印。
sed -n -i 's/pattern/replacement/p' "dir"/*
仅保存更改的记录
sed -i 's/pattern/replacement/g' "dir"/*
仅更改匹配记录