Wie schneide ich eine Datei unter Linux auf eine bestimmte Größe?

19

Ich möchte die Größe einer Datei brachial verkleinern, das heißt, ich kümmere mich nicht um den Rest, ich möchte nur die Datei etwa halbieren und den Rest wegwerfen.

Das erste, was mir einfällt, ist Perls Kürzung . Ich folge dem Beispiel auf dieser Seite und mache genau dasselbe:

seq 9 > test.txt
ls -l test.txt
perl -we 'open( FILE, "< ./test.txt" ) && truncate( FILE, 8 ) && close(FILE);'

Die Datei hat aber immer noch die gleiche Größe:

$ ls -lgG test.txt
-rw-rw---- 1 18 2013-08-08 09:49 test.txt

Wie kann ich das schaffen?

xpt
quelle

Antworten:

61

Möglicherweise möchten Sie den Befehl truncate verwenden :

truncate --size=1G test.txt

GRÖSSE kann in Byte, KB, K, MB, M usw. angegeben werden. Ich gehe davon aus, dass Sie die gewünschte Größe von Hand berechnen können. Andernfalls könnten Sie wahrscheinlich den Befehl stat verwenden, um Informationen über die aktuelle Größe der Datei abzurufen.

ChrisInEdmonton
quelle
Seine Dokumentation (im Info-Format) aus coreutils.
Cristian Ciupitu
21
perl -we 'open( FILE, "< ./test.txt" ) && truncate( FILE, 8 ) && close(FILE);'

öffnet die Datei zum Lesen. Um die Datei zu kürzen, müssen Sie sie jedoch ändern, damit ein schreibgeschütztes Dateihandle nicht funktioniert. Sie müssen den Modus "Ändern" ( "+>") verwenden.

Nebenbei wundert es mich immer, wenn Leute Systemanrufe stillschweigend ausfallen lassen und dann fragen, was schief gelaufen ist. Ein wesentlicher Teil der Problemdiagnose besteht darin, die erzeugte Fehlermeldung zu überprüfen. Selbst wenn Sie es nicht verstehen, erleichtert es denjenigen, die Sie um Hilfe bitten, das Leben erheblich.

Folgendes wäre etwas hilfreicher gewesen:

perl -we 'open(FILE, "<", "./test.txt") or die "open: $!";
          truncate(FILE, 8) or die "truncate: $!";
          close(FILE);'

obwohl zugegebenermaßen das nur "ungültiges Argument" gemeldet hätte. Trotzdem ist das eine nützliche Information und könnte Sie zu der Schlussfolgerung geführt haben, dass der offene Modus falsch war (wie bei mir).

rici
quelle
3

Sie können verwenden tail, um die letzten 100000 Bytes zu schneiden. Beispiel:

tail -c 100000 Datei> Datei2

Das -c gibt die letzten 100000 Bytes der Datei aus, um weitere Optionen zu erhalten:

mann schwanz

So ersetzen Sie die Originaldatei durch die soeben erstellte Datei:

MV-Datei2-Datei

Ivan Malyshev
quelle
2

Die Antwort oben unter Berufung auf truncate ist schön. dd erledigt auch die Arbeit:

dd if=test.txt of=test2.txt bs=1 count=8
mv test2.txt test.txt
James Georgas
quelle
1
Der Schlüsselbegriff lautet "zu einer bestimmten Größe" , sagen wir 1000. Ich werde stattdessen die Antwort auf die am häufigsten gewählte ändern, was für die direkte Eingabe funktioniert - es ist keine Zwischendatei erforderlich.
30.
0

Es gibt eine ganz andere Möglichkeit, dies mit bash mit dem Programm ed zu tun. Das folgende Skript speichert nur die letzten 5000 Zeilen aller Dateien im angegebenen Verzeichnis. Dies kann leicht geändert werden, um eine Schleife über mehrere Verzeichnisse zu erstellen, die Anzahl der Zeilen zu ändern usw.

#!/bin/bash

LOGDIR=/opt/log
SAVELINES=5000

dirs="$LOGDIR"
for dir in $dirs ; do
    files=${dir}/*
    for f in $files ; do
        echo -e "1,-${SAVELINES}d\nwq" | ed $f 1>/dev/null 2>&1
    done
done
Richard
quelle