Ich habe eine große Anzahl von Dateien, von denen einige sehr lang sind. Ich möchte sie auf eine bestimmte Größe kürzen, wenn sie größer sind, indem ich das Ende der Datei entferne. Ich möchte aber nur ganze Zeilen entfernen. Wie kann ich das machen? Es fühlt sich an wie die Art von Dingen, die von der Linux-Toolchain gehandhabt werden, aber ich kenne nicht den richtigen Befehl.
Angenommen, ich habe eine Datei mit 120.000 Byte und 300 Byte Zeilen und versuche, sie auf 10.000 Byte zu kürzen. Die ersten 33 Zeilen sollten bleiben (9900 Bytes) und der Rest sollte abgeschnitten werden. Ich möchte nicht auf 10.000 Bytes genau schneiden, da dies eine Teilzeile hinterlassen würde.
Natürlich sind die Dateien unterschiedlich lang und die Zeilen sind nicht alle gleich lang.
Idealerweise werden die resultierenden Dateien eher etwas kürzer als etwas länger (wenn sich der Haltepunkt in einer langen Zeile befindet), aber das ist nicht allzu wichtig, es könnte etwas länger sein, wenn das einfacher ist. Ich möchte, dass die Änderungen direkt an Dateien vorgenommen werden (naja, möglicherweise wird die neue Datei an eine andere Stelle kopiert, das Original gelöscht und die neue Datei verschoben, aber das ist das gleiche aus der Sicht des Benutzers). Eine Lösung, die Daten an eine Reihe von Stellen und wieder zurückleitet, bietet die Möglichkeit, die Datei zu beschädigen, und ich möchte dies vermeiden ...
quelle
Antworten:
Die
sed
/wc
Komplexität kann in vorherigen Antworten vermieden werden, wennawk
verwendet wird. Am Beispiel von OP ( vollständige Zeilen vor 10000 Bytes):Zeigt auch die komplette Zeile mit dem 10000. Byte an, wenn dieses Byte nicht am Ende der Zeile steht:
Die obige Antwort setzt voraus:
\n
).\r\n
Ändern Sielength() + 1
für DOS / Windows-Textdateien ( ) zulength() + 2
LC_CTYPE=C
, dass die Interpretation auf Byte-Ebene erzwungen wird.quelle
Der
sed
Ansatz ist in Ordnung, aber nicht über alle Linien zu schleifen. Wenn Sie wissen, wie viele Zeilen Sie behalten möchten (um ein Beispiel zu haben, verwende ich hier 99), können Sie dies folgendermaßen tun:Erläuterung: Ist
sed
ein Prozessor für reguläre Ausdrücke. Mit der angegebenen Option-i
wird eine Datei direkt ("inline") verarbeitet, anstatt sie nur zu lesen und die Ergebnisse in die Standardausgabe zu schreiben.100,$
bedeutet nur "von Zeile 100 bis zum Ende der Datei" - gefolgt von dem Befehld
, von dem Sie wahrscheinlich richtig vermutet haben, dass er für "Löschen" steht. Kurz gesagt bedeutet der Befehl: "Löschen Sie alle Zeilen von Zeile 100 bis zum Ende der Datei aus myfile.txt". 100 ist die erste Zeile, die gelöscht werden soll, da 99 Zeilen beibehalten werden sollen.Bearbeiten: Wenn es andererseits Protokolldateien gibt, in denen Sie z. B. die letzten 100 Zeilen speichern möchten :
Was geht hier vor sich:
[ $(wc -l myfile.txt) -gt 100 ]
: Führen Sie die folgenden Schritte aus, wenn die Datei mehr als 100 Zeilen enthält$((100 - $(wc -l myfile.txt|awk '{print $1}')))
: Anzahl der zu löschenden Zeilen berechnen (dh alle Zeilen der Datei mit Ausnahme der (letzten) 100, die beibehalten werden sollen)1, $((..)) d
: Alle Zeilen von der ersten bis zur berechneten Zeile entfernenBEARBEITEN: Da die Frage soeben bearbeitet wurde, um weitere Details zu liefern, werde ich diese zusätzlichen Informationen auch in meine Antwort aufnehmen. Hinzugefügte Fakten sind:
Aus diesen Daten ist es möglich, die Anzahl der verbleibenden Zeilen als "/" zu berechnen, was im Beispiel 33 Zeilen bedeuten würde. Der Shell-Begriff für die Berechnung:
$((size_to_remain / linesize))
(Zumindest unter Linux mit Bash ist das Ergebnis eine Ganzzahl). Der angepasste Befehl würde jetzt lauten:Da die Größen im Voraus bekannt sind, ist keine in den
sed
Befehl eingebettete Berechnung mehr erforderlich . Aus Gründen der Flexibilität kann man in einigen Shell-Skripten Variablen verwenden.Für die bedingte Verarbeitung basierend auf der Dateigröße kann das folgende "test" -Konstrukt verwendet werden:
was bedeutet: "Wenn die Größe
$file
100kB überschreitet, mache ..." (ls -lk
listet die Dateigröße in kB an Position 5 auf und wird daherawk
verwendet, um genau dies zu extrahieren).quelle
head -n
.Da ich keinen entsprechenden Befehl gefunden habe, habe ich ein schnelles Skript geschrieben (nicht getestet):
quelle
Sie können den Linux-Befehl sed verwenden, um Zeilen aus einer Datei zu entfernen. Mit dem folgenden Befehl löschen Sie die letzte Zeile der Datei filename.txt:
Mit awk oder find können Sie nach Mustern suchen, die Ihrem sed-Befehl entsprechen. Zuerst suchst du mit awk oder suchst nach den Dateien, die du kürzen möchtest und dann kannst du die Zeilen mit sed entfernen.
quelle
Ich habe etwas ähnliches mit Schwanz gemacht. So behalten Sie in diesem Fall nur die letzten 10.000 Zeilen bei:
quelle