Find and replace in file and overwrite file doesn&

2019-09-03 09:21发布

I would like to run a find and replace on an HTML file through the command line.

My command looks something like this:

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

When I run this and look at the file afterward, it is empty. It deleted the contents of my file.

When I run this after restoring the file again:

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

The stdout is the contents of the file, and the find and replace has been executed.

Why is this happening?

13条回答
2楼-- · 2019-09-03 10:12

You can use Vim in Ex mode:

ex -sc '%s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g|x' index.html
  1. % select all lines

  2. x save and close

查看更多
干净又极端
3楼-- · 2019-09-03 10:15

The problem with the command

sed 'code' file > file

is that file is truncated by the shell before sed actually gets to process it. As a result, you get an empty file.

The sed way to do this is to use -i to edit in place, as other answers suggested. However, this is not always what you want. -i will create a temporary file that will then be used to replace the original file. This is problematic if your original file was a link (the link will be replaced by a regular file). If you need to preserve links, you can use a temporary variable to store the output of sed before writing it back to the file, like this:

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

Better yet, use printf instead of echo since echo is likely to process \\ as \ in some shells (e.g. dash):

tmp=$(sed 'code' file); printf "%s" "$tmp" > file
查看更多
来,给爷笑一个
4楼-- · 2019-09-03 10:16

With all due respect to the above correct answers, it's always a good idea to "dry run" scripts like that, so that you don't corrupt your file and have to start again from scratch.

Just get your script to spill the output to the command line instead of writing it to the file, for example, like that:

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

OR

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

This way you can see and check the output of the command without getting your file truncated.

查看更多
等我变得足够好
5楼-- · 2019-09-03 10:20

You should try using the option -i for in-place editing.

查看更多
放我归山
6楼-- · 2019-09-03 10:20

And the ed answer:

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

To reiterate what codaddict answered, the shell handles the redirection first, wiping out the "input.html" file, and then the shell invokes the "sed" command passing it a now empty file.

查看更多
时光不老,我们不散
7楼-- · 2019-09-03 10:23
sed -i 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' index.html

This does a global in-place substitution on the file index.html. Quoting the string prevents problems with whitespace in the query and replacement.

查看更多
登录 后发表回答