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

我的命令看起来像这样:

sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html

当我运行它并在之后查看该文件时,它是空的。它删除了我文件的内容。

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

sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html

stdout是文件的内容,并且已经执行了查找和替换。

为什么会这样?


当前回答

使用sed的-i选项,例如:

sed -i bak -e s/STRING_TO_REPLACE/REPLACE_WITH/g index.html

其他回答

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

要解决这个问题,你需要将-i选项传递给sed,以便内联更改,并在它执行更改之前创建原始文件的备份:

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

如果没有.bak,该命令将在某些平台上失败,例如Mac OSX。

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

这将对文件index.html进行全局就地替换。引用字符串可以防止查询和替换中出现空白的问题。

警告:这是一个危险的方法!它滥用了linux中的i/o缓冲区,通过特定的缓冲选项,它可以处理小文件。这是一件有趣的奇事。但是不要在真实的情况下使用它!

除了sed的-i选项 您可以使用tee实用程序。

从男人:

Tee -从标准输入读取并写入标准输出和文件

所以,解决方案是:

sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee | tee index.html

-- here the tee is repeated to make sure that the pipeline is buffered. Then all commands in the pipeline are blocked until they get some input to work on. Each command in the pipeline starts when the upstream commands have written 1 buffer of bytes (the size is defined somewhere) to the input of the command. So the last command tee index.html, which opens the file for writing and therefore empties it, runs after the upstream pipeline has finished and the output is in the buffer within the pipeline.

下面的方法很可能行不通:

sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee index.html

-- it will run both commands of the pipeline at the same time without any blocking. (Without blocking the pipeline should pass the bytes line by line instead of buffer by buffer. Same as when you run cat | sed s/bar/GGG/. Without blocking it's more interactive and usually pipelines of just 2 commands run without buffering and blocking. Longer pipelines are buffered.) The tee index.html will open the file for writing and it will be emptied. However, if you turn the buffering always on, the second version will work too.

使用sed的-i选项,例如:

sed -i bak -e s/STRING_TO_REPLACE/REPLACE_WITH/g index.html

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