Ich versuche, die letzten 50 Zeilen in meiner Datei zu behalten, wobei ich jede Minute Temperatur speichere. Ich habe diesen Befehl benutzt:
tail -n 50 /home/pi/Documents/test > /home/pi/Documents/test
Das Ergebnis ist jedoch eine leere Testdatei. Ich dachte, es werden die letzten 50 Zeilen der Testdatei aufgelistet und in die Testdatei eingefügt. Wenn ich diesen Befehl verwende:
tail -n 50 /home/pi/Documents/test > /home/pi/Documents/test2
es funktioniert gut. Die Datei test2 enthält 50 Zeilen.
Kann mir jemand erklären, wo das Problem liegt?
command-line
logs
tail
dorinand
quelle
quelle
logging
Modul ansehenAntworten:
Das Problem ist, dass Ihre Shell die Befehlspipeline einrichtet, bevor Sie die Befehle ausführen. Es geht nicht um "Ein- und Ausgabe", sondern darum, dass der Inhalt der Datei bereits verschwunden ist, bevor Tail überhaupt ausgeführt wird. Es geht so etwas wie:
>
Ausgabedatei zum Schreiben und schneidet sie abtail
.tail
läuft, öffnet/home/pi/Documents/test
und findet dort nichtsEs gibt verschiedene Lösungen, aber der Schlüssel ist, das Problem zu verstehen, was tatsächlich schief geht und warum.
Dies wird produzieren, was Sie suchen,
Erklärung:
$()
wird als Befehlsersetzung bezeichnet, die ausgeführt wirdtail -n 50 /home/pi/Documents/test
> /home/pi/Documents/test
Leitet die Ausgabeecho "$(tail -n 50 /home/pi/Documents/test)"
in dieselbe Datei um.quelle
bash: xrealloc: cannot allocate 18446744071562067968 bytes
Eine andere Lösung für
sponge
diemoreutils
Dateiumleitung, bei der zuerst die Datei gelöscht wird, besteht darin, aus dem Paket Folgendes zu verwenden :quelle
Dies liegt daran, dass bash die Umleitung mit der
>
ersten verarbeitet und den Inhalt der Datei löscht. Dann führt es den Befehl aus. Wenn Sie verwenden>>
, werden die letzten 50 Zeilen an das Ende des aktuellen Inhalts der Datei angehängt. In diesem Fall müssten Sie die gleichen 50 Zeilen zweimal wiederholen.Der Befehl funktioniert beim Umleiten in eine andere Datei wie erwartet. Hier ist eine Möglichkeit, die letzten 50 Zeilen einer Datei in eine Datei mit demselben Namen zu schreiben:
Dabei werden zuerst die letzten 50 Zeilen in eine temporäre Datei geschrieben, die dann mit verschoben wird
mv
, um die ursprüngliche Datei zu ersetzen.Wie in den Kommentaren erwähnt, funktioniert dies nicht, wenn die Datei noch geöffnet ist. Durch das Verschieben der Datei wird auch ein neuer Inode erstellt, und möglicherweise werden Eigentümer und Berechtigungen geändert. Ein besserer Weg, dies mit einer temporären Datei zu tun, wäre:
Die temporäre Datei kann auch entfernt werden, wobei der Inhalt jedes Mal überschrieben wird.
quelle
tail -50 /home/pi/Documents/test >/tmp/foo && cat /tmp/foo >/home/pi/Documents/test
tail ... > temp ; cat temp > orig ; rm -f temp
funktioniert.Da Sie das Hauptproblem bei der Shell-Umleitung gesehen haben, haben Sie hier eine alternative Möglichkeit, eine Datei auf die letzten 50 Zeilen zu beschränken:
Die harte Arbeit erledigt (GNU) sed mit der Funktion
-i
"In-Place-Bearbeitung", die im Hintergrund funktioniert, indem sie die Ausgabe in einer temporären Datei erstellt. Der Rest der Zeilen richtet die Mathematik für die Operation von sed ein, nämlich:wc
) und subtrahiere dann 50; weise das zun
.n
positiv ist, führen Sie den Befehl sed aus, um die Zeilen 1 bis n zu löschen.quelle
printf
wird verwendet, um Befehle (einen pro Zeile) weiterzuleitened
. Dieed
Befehle sind:1,$-50d
- Alle bis auf die letzten 50 Zeilen löschenw
- Geänderte Datei zurück auf die Festplatte schreibenDa keine Umleitungen erforderlich sind, kann die Shell die Ausgabedatei nicht überschreiben, bevor sie gelesen wurde.
Im Gegensatz zu den meisten Formen der direkten Bearbeitung (bei denen in der Regel nur die direkte Bearbeitung simuliert wird, indem eine temporäre Datei erstellt und dann über dem Original umbenannt wird) wird
ed
die ursprüngliche Datei tatsächlich bearbeitet. und Eigentümer, Gruppe und Berechtigungen - tempfile + mv ändert immer den Inode und kann je nach Umständen die anderen ändern.quelle
Auf einer etwas anderen Spur können Sie
logrotate(8)
die Protokolldateien regelmäßig in inkrementell benannte Dateien sichern und dann alte löschen.Auf diese Weise werden die Hauptprotokolldateien des Systems verwaltet, um zu verhindern, dass sie zu lang werden.
quelle