猫,Grep,redirect输出…空白文件?

我刚刚跑了

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是空白的。

任何人都可以向我解释为什么发生这种情况,或者我应该这样做的正确方法吗?

发生这种情况是因为第一件事就是创build要写入的文件,如果文件已经存在,其内容将被删除。 (另外,在你的语句中根本不需要使用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 

会工作。

当redirect到同一个文件( > )时,shell可能会在调用cat命令并读取input之前创build/截断文件(请参阅: 为什么不排列“file1> file1”? 如果要过滤文件,最好将输出redirect到不同的文件,或者根本不要redirect,例如:

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

更好更安全的方法是使用专为这种操作而devise的就地编辑器,

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

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

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

有关:

  • 在SO中删除包含特定string的文本文件中的行
  • 将文件inputredirect到 SO中的相同文件