sed command creates a file with 0 bytes

2019-08-12 05:56发布

I have a shell script which copies an xml file and places it a directory. Now once the xml is copied, I perform a sed operation to replace a tag value with some other value. I am using the following command:

sed "s#ABC-XYZ#DEF-PQR#g" test.xml > test-newfile.xml

The command executes properly but it creates the new xml "test-newfile.xml" with size 0 bytes. So I guess, this command is working but somehow not able to create the new copy of the xml.

The test.xml is not empty:

-rw-rw-r-- 1 sujeet11 sujeet   0 May 28 23:06 test-newfile.xml
-rw-rw-r-- 1 sujeet11 sujeet 555 May 28 23:04 test.xml

Now here is the interesting part: If I open the test.xml in vi mode and without making any changes to the xml, if I save it using :wq and then perform the same sed operation, it substitutes the string and creates the newfile copy with the updated string.

标签: shell sed
1条回答
叛逆
2楼-- · 2019-08-12 06:35

Transferring some comments into an answer.

It sounds as if you're missing a newline at the end of the file (and there's only one line of data in the file). When you edit, vim will add the newline. I was trying that as a possible source of trouble; both GNU sed and BSD sed on Mac OS X 10.9.3 are OK with a file consisting of a null byte, 500 x's and no newline (or the same with a newline at the end).

Does the failing test.xml end with a newline? Does the copy of the file edited with vim end with a newline? If the one fails and the other succeeds, that is the problem — text files are supposed to end with a newline, and you invoke undefined behaviour if the file does not end with a newline. Many versions of sed will work anyway; some will not.

Yes, you are right. The failing test.xml does not end with a new line. Once I edit it with vim, it ends with a newline. Thanks! How am I going to take care of it? Any other method to append a new line before performing the sed operation?

It might be easiest to add a newline to the end of the file regardless of whether one exists already, maybe using:

echo "" >>test.xml

You can then use:

sed -e 's#ABC-XYZ#DEF-PQR#g' -e '/^$/d' test.xml

to eliminate all empty lines (or -e '${/^$/d;}' to remove an empty final line in the file), undoing the damage wrought by the echo if the file already ended with a newline.

查看更多
登录 后发表回答