Aufgrund eines noch nicht diagnostizierten Anwendungsfehlers habe ich mehrere hundert Server mit einer vollen Festplatte. Es gibt eine Datei, die mit doppelten Zeilen gefüllt wurde - keine Protokolldatei, sondern eine Benutzerumgebungsdatei mit Variablendefinitionen (daher kann ich die Datei nicht einfach löschen).
Ich schrieb einen einfachen sed
Befehl, um nach den irrtümlich hinzugefügten Zeilen zu suchen und sie zu löschen, und testete ihn an einer lokalen Kopie der Datei. Es hat wie beabsichtigt funktioniert.
Als ich es jedoch auf dem Server mit der vollständigen Festplatte versuchte, wurde ungefähr der folgende Fehler angezeigt (es stammt aus dem Speicher, nicht aus dem Kopieren und Einfügen):
sed: couldn't flush /path/to/file/sed8923ABC: No space left on deviceServerHostname
Natürlich weiß ich , dass kein Platz mehr vorhanden ist. Deshalb versuche ich Sachen zu löschen! (Der von sed
mir verwendete Befehl reduziert eine Datei mit mehr als 4000 Zeilen auf etwa 90 Zeilen.)
Mein sed
Befehl ist gerechtsed -i '/myregex/d' /path/to/file/filename
Gibt es eine Möglichkeit, diesen Befehl trotz der vollen Festplatte anzuwenden?
(Es muss automatisiert werden, da ich es als schnelle Lösung auf mehrere hundert Server anwenden muss.)
(Natürlich muss der Anwendungsfehler diagnostiziert werden, aber in der Zwischenzeit funktionieren die Server nicht richtig ....)
Update: Die Situation, mit der ich konfrontiert war, wurde gelöst, indem etwas anderes gelöscht wurde, von dem ich herausgefunden habe, dass ich es löschen kann. Ich möchte jedoch weiterhin die Antwort auf diese Frage, die in Zukunft und für andere Personen hilfreich sein würde.
/tmp
ist ein No-Go; Es befindet sich im selben Dateisystem.
Bevor ich Speicherplatz freigegeben habe, habe ich getestet und herausgefunden, dass ich die Zeilen löschen kann, indem ich vi
die Datei öffne :g/myregex/d
und ausführe und die Änderungen dann erfolgreich mit speichere :wq
. Es scheint möglich zu sein, dies zu automatisieren, ohne auf ein separates Dateisystem zurückzugreifen, um eine temporäre Datei zu speichern .... (?)
sed -i
Erstellt eine temporäre Kopie für die Bearbeitung. Ich vermute, das ed
wäre besser dafür, obwohl ich nicht vertraut genug bin, um eine tatsächliche Lösung zu verbieten
ed
Sie ausführen: printf %s\\n g/myregex/d w q | ed -s infile
aber denken Sie daran , dass einige Implementierungen auch temporäre Dateien verwenden, genau wie sed
(Sie könnten Busybox Ed ausprobieren - afaik es erstellt keine temporäre Datei)
echo
. verwenden printf
. und sed
fügen Sie ein Zeichen hinzu, das Sie in der letzten Zeile ablegen, damit Sie nicht nachgestellte Leerzeichen verlieren. Außerdem muss Ihre Shell in der Lage sein, die gesamte Datei in einer einzigen Befehlszeile zu verarbeiten. Das ist dein Risiko - zuerst testen. bash
ist besonders schlecht dabei (ich denke, es ist mit Stapelplatz zu tun?) und kann Sie jederzeit krank machen. Die beiden sed
empfohlenen würden zumindest den Pipe-Puffer des Kernels verwenden, um eine gute Wirkung zwischen ihnen zu erzielen, aber die Methode ist ziemlich ähnlich. Ihre Befehlsunterfunktion schneidet auch ab, file
ob das sed w / in erfolgreich ist oder nicht.
sed '/regex/!H;$!d;x' <file|{ read v && cat >file;}
und wenn es funktioniert, lies den Rest meiner Antwort. '