不使用 grep 清空文件,随后将其视为二进制文件

不使用 grep 清空文件,随后将其视为二进制文件

目前我有netcat管道输出tee正在写入output.txt

nc -l -k -p 9100 | tee output.txt

我想监视这个输出,所以我通过tail -f | egrep -i 'regex'PuTTY 观看它,这样我就只能看到相关的位。

我时不时地想清除输出文件。出现的问题是,如果我这样做> output.txt然后再次尝试,tail -f | egrep ...我不会得到任何输出。如果我 grep 浏览该文件,我不会得到任何匹配项,尽管知道有应该匹配(cat output.txt正确吐出文件)

mitch@quartz:~$ grep output.txt -e 'regex'
Binary file output.txt matches

而对output.txt使用相同的命令清空它效果很好。

基本上:>让人grep认为我的文件是二进制文件,并且无法正确搜索。有没有更好的方法来清除文件?

答案1

如果唯一的问题是grep将其视为二进制,则告诉grep无论如何都要搜索它:

$ head /bin/bash > out
$ echo "test" >> out 
$ grep test out 
Binary file out matches
$ grep -a test out 
test

man grep

   -a, --text
          Process  a binary file as if it were text; this is equivalent to
          the --binary-files=text option.

答案2

它可能会回答您的问题,所以这是我刚刚运行的一些测试的结果:

$ > output.txt
$ file output.txt
output.txt: empty

$ echo "" > output.txt
$ file output.txt
output.txt: very short file (no magic)

$ echo " " > output.txt
$ file output.txt
output.txt : ASCII text

正如您所看到的,该文件的分类方式与您实际的内容不同“放当您尝试清除它时,其中包含“。因此,您可能需要使用空字符串而不是什么都没有。

答案3

>使 grep 认为该文件是二进制的,因为它是二进制的。问题是,您清空了文件,但没有停止填充该文件的程序。

>output.txtoutput.txt如果不存在则创建,如果存在则将其截断为零长度。

在您运行时>output.txt,有一个tee进程打开了该文件。截断文件不会影响tee写入的位置。假设它已经写了截断前的字节。tee截断后下次写入时,会从该位置开始写入。允许在文件当前末尾之外的位置进行写入,并用空字节填充文件的开头。 正是此处发生的情况。

Grep 看到一个以一些空字节开头的文件。它正确地将文件报告为二进制文件。

您可以通过调用 来告诉 GNU grep 将文件视为文本grep -a。它将搜索整个文件,包括空字节(它们不匹配,因此它们不会影响结果,除非第一行有匹配,但如果它们很多,它们可能会导致速度减慢)。

更好的解决方案是告诉tee始终在文件的当前末尾写入。幸运的是(如斯蒂芬·查泽拉斯评论),有一个选项:(tee -a存在于所有 POSIX 兼容系统上)。您需要先截断该文件。

>output.txt
nc -l -k -p 9100 | tee -a output.txt

大部分文件系统允许完全由空字节组成的块保持未分配状态。这种特殊的压缩方法称为制作稀疏文件

相关内容