sed命令在文件中查找和replace,覆盖文件不起作用,它清空文件

我想通过命令行在HTML文件上运行查找和replace。

我的命令看起来像这样:

sed -es/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html 

当我运行这个,然后看文件时,它是空的。 它删除了我的文件的内容。

当我再次恢复文件后运行这个:

 sed -es/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html 

stdout是文件的内容,查找和replace已经执行。

为什么发生这种情况?

shell在命令行中看到> index.html ,它会打开文件index.html进行写入 ,擦除所有以前的内容。

要解决此问题,需要将-i选项传递给sed以进行内联更改,并在原地更改之前创build原始文件的备份:

 sed -i.bak s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html 

如果没有.bak,那么命令在某些平台(如Mac OSX)上将失败。

另一种有用的模式是:

 sed -e 'script script' index.html > index.html.tmp && mv index.html.tmp index.html 

这有很多相同的效果,而不使用-i选项,另外意味着,如果sed脚本由于某种原因失败,input文件不会被破坏。 此外,如果编辑成功,则没有备份文件留下。 这种成语在Makefiles中很有用。

相当多的seds都有-i选项,但不是全部。 posix sed是没有的。 如果你的目的是便携性,那么最好避免。

 sed -i 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' index.html 

这对文件index.html进行全局就地replace。 引用该string可防止查询和replace中的空白问题。

使用sed的-i选项,例如

 sed -i bak -es/STRING_TO_REPLACE/REPLACE_WITH/g index.html 

要更改多个文件(并将每个文件的备份保存为* .bak):

 perl -p -i -e "s/\|/x/g" * 

将取出目录中的所有文件并replace|x这叫做“Perl派”(很容易就像派)

您应该尝试使用选项-i进行就地编辑。

除了sed-i选项,你可以使用tee工具

man

tee – 从标准input读取并写入标准输出和文件

所以,解决scheme将是:

 sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee index.html 
 sed -i.bak "s#https.*\.com#$pub_url#g" MyHTMLFile.html 

如果你有一个要添加的链接,试试这个。 按上述方式searchURL(以https开头,以.com结尾),并将其replace为URLstring。 我在这里使用了一个variables$pub_url 。 这里意味着search和g意味着全球替代。

有用 !

和答的答案:

 printf "%s\n" '1,$s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' wq | ed index.html 

为了重申codaddict的回答 ,shell 首先处理redirect,清除“input.html”文件, 然后 shell调用“sed”命令传递一个空文件。

命令的问题

 sed 'code' file > file 

在sed实际得到处理它之前,该file被shell截断了。 结果,你得到一个空文件。

执行此操作的sed方式是使用-i来编辑,如其他答案所示。 但是,这并不总是你想要的。 -i将创build一个临时文件,然后用它来replace原始文件。 这是有问题的,如果你的原始文件是一个链接(链接将被replace为一个普通的文件)。 如果您需要保留链接,您可以使用临时variables来存储sed的输出,然后将其写回到文件中,如下所示:

 tmp=$(sed 'code' file); echo -n "$tmp" > file 

更好的是,使用printf而不是echo因为echo可能在某些shell(例如短划线)中将\\处理为\

 tmp=$(sed 'code' file); printf "%s" "$tmp" > file 

您可以在Ex模式下使用Vim:

 ex -sc '%s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g|x' index.html 
  1. %select所有行

  2. 保存并closures

我正在寻找可以定义行范围并find答案的选项。 例如,我想从第36-57行将host1更改为host2。

 sed '36,57 s/host1/host2/g' myfile.txt > myfile1.txt 

您也可以使用gi选项来忽略字符大小写。

 sed '30,40 s/version/story/gi' myfile.txt > myfile1.txt 

对于上述正确答案的所有应有的尊重,这样的“干运行”脚本总是一个好主意,这样你就不会损坏你的文件,而必须从头开始重新开始。

只要让脚本将输出泄露到命令行而不是将其写入文件,例如:

 sed -es/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html 

要么

 less index.html | sed -es/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g 

这样你可以看到并检查命令的输出,而不会让你的文件被截断。