Leeren Sie eine Datei ohne grep und behandeln Sie sie anschließend wie eine Binärdatei

Leeren Sie eine Datei ohne grep und behandeln Sie sie anschließend wie eine Binärdatei

Derzeit habe ich netcateine Piping-Ausgabe, teedie in output.txt geschrieben wird mit

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

Ich möchte diese Ausgabe überwachen, also beobachte ich sie mit tail -f | egrep -i 'regex'PuTTY, sodass ich nur die relevanten Teile sehe.

Hin und wieder möchte ich die Ausgabedatei löschen. Das Problem tritt auf, dass ich keine Ausgabe erhalte, wenn ich dies tue > output.txtund es dann erneut versuche tail -f | egrep .... Wenn ich die Datei durchsuche, erhalte ich keine Übereinstimmungen, obwohl ich weiß, dass essollenÜbereinstimmungen aufweisen (da cat output.txtdie Datei ordnungsgemäß ausgegeben wird)

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

Während der gleiche Befehl auf output.txtVordas Entleeren funktioniert einwandfrei.

Im Grunde: >Es lässt mich grepdenken, meine Datei sei eine Binärdatei und es wird nicht richtig gesucht. Gibt es eine bessere Möglichkeit, die Datei zu löschen?

Antwort1

Wenn das einzige Problem darin besteht, dass grepes als Binärdatei behandelt wird, weisen Sie an, greptrotzdem danach zu suchen:

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

Aus man grep:

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

Antwort2

Es könnte Ihre Frage beantworten, also hier die Ergebnisse einiger Tests, die ich gerade durchgeführt habe:

$ > 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

Wie Sie sehen, wird die Datei nicht auf die gleiche Weise kategorisiert, je nachdem, was Sie tatsächlich"setzen" darin, wenn Sie versuchen, es zu löschen. Daher möchten Sie möglicherweise eine leere Zeichenfolge anstelle von gar nichts verwenden.

Antwort3

>lässt grep denken, dass die Datei binär ist, weil sie binär ist. Der Punkt ist, dass Sie die Datei geleert, aber das Programm, das sie gefüllt hat, nicht gestoppt haben.

>output.txterstellt, output.txtwenn es nicht existiert, und kürzt es auf die Länge Null, wenn es existiert.

An der Stelle, an der Sie ausführen >output.txt, ist ein teeProzess vorhanden, der die Datei geöffnet hat. Das Abschneiden der Datei hat keinen Einfluss auf die Position, an der teegeschrieben wird. Nehmen wir an, es wurde geschriebenNBytes vor der Kürzung. Beim nächsten teeSchreiben nach der Kürzung wird an PositionN. Das Schreiben an einer Position hinter dem aktuellen Dateiende ist zulässig und füllt den Anfang der Datei mit Nullbytes.¹ Das ist hier passiert.

Grep erkennt eine Datei, die mit einigen Nullbytes beginnt. Es meldet die Datei korrekt als binär.

Sie können GNU grep anweisen, die Datei als Text zu behandeln, indem Sie aufrufen grep -a. Es durchsucht die gesamte Datei, einschließlich der Nullbytes (die nicht übereinstimmen, sodass sie das Ergebnis nicht beeinflussen, sofern es keine Übereinstimmung in der ersten Zeile gibt, aber sie können zu einer Verlangsamung führen, wenn es viele davon gibt).

Eine bessere Lösung ist, teeimmer an das aktuelle Ende der Datei zu schreiben. Glücklicherweise (wieStephane Chazelas bemerkte), gibt es dafür eine Option: tee -a(auf allen POSIX-kompatiblen Systemen vorhanden). Sie müssen die Datei zuerst kürzen.

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

¹ Die meisten Dateisysteme erlauben es, Blöcke, die komplett aus Nullbytes bestehen würden, nicht zuzuweisen. Diese spezielle Methode der Komprimierung nennt manSparse-Datei.

verwandte Informationen