Cat、Grep、重定向输出....空白文件?

Cat、Grep、重定向输出....空白文件?

我刚刚跑了

cat /opt/webapplications/Word/readme.log | grep -v 'Apple'

并且我在 CLI 上获得了我所期望的输出,即所有readme.log不包含“ Apple”的行...

接下来我跑了……

cat /opt/webapplications/Word/readme.log | grep -v 'Apple' > /opt/webapplications/Word/readme.log

但是,/opt/webapplications/Word/readme.log是空白的。

谁能向我解释为什么会发生这种情况,或者我应该采取正确的方法来解决这个问题?

答案1

发生这种情况是因为首先>要创建要写入的文件 - 如果该文件已存在,则其内容将被删除。 (此外,完全没有必要cat在语句中使用,因为grep它适用于文件,而不仅仅是 STDIN。)

正确的做法是使用临时文件来读取或写入。因此

cp /opt/webapplications/Word/readme.log /tmp/readme.log
grep -v 'Apple' /tmp/readme.log > /opt/webapplications/Word/readme.log

或者

grep -v 'Apple' /opt/webapplications/Word/readme.log > /tmp/readme.log
mv /tmp/readme.log /opt/webapplications/Word/readme.log

会工作。

答案2

当重定向到同一个文件(>)时,shell 可能会在cat调用命令和读取输入之前创建/截断该文件(参见:为什么“sort file1 > file1”不起作用?)。如果要过滤文件,最好将输出重定向到不同的文件,或者完全避免重定向,例如:

grep -v 'Apple' readme.log | tee readme.log

更好、更安全的方法是使用专门为此类操作设计的就地编辑器,例如

sed -i '.bak' '/Apple/d' readme.log

或者使用ex(Vim 的一部分):

ex +g/Apple/d -cwq readme.log

有关的:

相关内容