Cat, Grep, Redirect Output.... Blank File?
I just ran
cat /opt/webapplications/Word/readme.log | grep -v 'Apple'
and I got the output on the cli that I was expecting, which was all the lines in readme.log
that did not contain 'Apple
'...
Next I ran...
cat /opt/webapplications/Word/readme.log | grep -v 'Apple' > /opt/webapplications/Word/readme.log
However, /opt/webapplications/Word/readme.log
is blank.
Can anyone explain to me why this happened, or the correct way I should have gone about this?
This happened because the first thing >
does is to create the file it wants to write to - and if the file already exists, its contents will be deleted. (Also, there's no need at all to use cat
in your statement since grep
works on files, not just on STDIN.)
The correct way to do this is to use a temporary file either to read from or to write to. So either
cp /opt/webapplications/Word/readme.log /tmp/readme.log
grep -v 'Apple' /tmp/readme.log > /opt/webapplications/Word/readme.log
or
grep -v 'Apple' /opt/webapplications/Word/readme.log > /tmp/readme.log
mv /tmp/readme.log /opt/webapplications/Word/readme.log
would work.
When doing redirect into the same file (>
), shell may create/truncate the file before the cat
command is invoked and the input is read (see: Why doesn't “sort file1 > file1” work?). If you want to filter the file, it's better to redirect the output into different file, or avoid redirection at all, for example:
grep -v 'Apple' readme.log | tee readme.log
The better and safer way is to use in-place editors which are designed for that kind of operations, e.g.
sed -i '.bak' '/Apple/d' readme.log
or use ex
(part of Vim):
ex +g/Apple/d -cwq readme.log
Related:
- Delete lines in a text file that containing a specific string at SO
- Redirect input from file back into same file at SO