Wie kann ich gzip anweisen, die Originaldatei beizubehalten?

210

Ich möchte eine Textdatei mit dem gzip-Kommandozeilen-Tool komprimieren und dabei die Originaldatei behalten . Führen Sie standardmäßig den folgenden Befehl aus

gzip file.txt

führt dazu, dass diese Datei geändert und umbenannt wird file.txt.gz. Anstelle dieses Verhaltens möchte ich diese neue komprimierte Datei zusätzlich zu der vorhandenen haben file.txt. Im Moment benutze ich den folgenden Befehl, um das zu tun

gzip -c file.txt > file.txt.gz

Es funktioniert, aber ich frage mich, warum es keine einfachere Lösung gibt, um eine solche gemeinsame Aufgabe zu erledigen. Vielleicht habe ich die Möglichkeit verpasst, das zu tun?

Manuel Selva
quelle
3
Dies liegt daran, dass gzip die angegebene Datei komprimiert und eine neue Datei erstellt. Komprimierung bedeutet, die ursprüngliche Datei zu komprimieren und durch eine neue zu ersetzen. Ihre Option "-c" weist gzip explizit an, sie unter einem anderen Namen zu speichern. Deshalb funktioniert es
SHW
@SHW Ich habe deinen Kommentar nicht bekommen ...?
Manuel Selva
@ManuelSelva Sobald die Originaldatei komprimiert ist, wird sie nicht mehr benötigt. Ich denke, das war das Design.
Daisy
2
Warum gzip / gunzip dies standardmäßig tun, wenn kein anderes Unix-Tool dies tut, ist mir ein Rätsel .
Mateen Ulhaq

Antworten:

247

Informationen zu GNU gzip1.6 oder höher, FreeBSD und Derivaten oder neueren Versionen von NetBSD finden Sie in der Antwort von don_cristi .

In jeder Version können Sie Shell-Umleitungen wie folgt verwenden:

gzip < file > file.gz

Wenn kein Argument angegeben wird, wird gzipdie Standardeingabe gelesen, komprimiert und die komprimierte Version in die Standardausgabe geschrieben. Als Bonus müssen Sie sich bei der Verwendung von Shell-Umleitungen keine Gedanken darüber machen, ob Dateien aufgerufen werden "--help"oder "-"(für letztere ist dies immer noch ein Problem gzip -c --).

Ein weiterer Vorteil gzip -c file > file.gzist, dass fileder Befehl fehlschlägt , wenn er nicht geöffnet werden kann, ohne dass ein leerer Befehl erstellt file.gz(oder ein vorhandener überschrieben wird file.gz) und ohne dass er ausgeführt wird gzip.

Ein wesentlicher Unterschied zu gzip -kobwohl ist, dass es keinen Versuch geben wird, die fileMetadaten (Eigentum, Berechtigungen, Änderungszeit, Name der nicht komprimierten Datei) zu kopieren file.gz.

Auch wenn es file.gzbereits existiert, wird es stillschweigend überschrieben, es sei denn, Sie haben die noclobberOption in Ihrer Shell aktiviert ( set -o noclobberzum Beispiel in POSIX-Shells).

Stéphane Chazelas
quelle
4
Damit werden nun die Besonderheiten der OP-Frage angesprochen und die allgemeine Frage beantwortet, wie gzip angewiesen wird, die Originaldatei zu behalten. Sehr praktisch und nützlicher als -c.
Codewaggle
8
Beachten Sie, dass die <und> eigentlich in den Befehl eingegeben werden sollen und keinen Platzhalter für den Dateinamen darstellen
Gaurav Gupta
Was ist die -kOption? Konnte es nicht in den Manpages finden, zB diese Version hier linux.die.net/man/1/gzip . Außerdem sieht es so aus, als würde gzip standardmäßig die Metadaten der Datei kopieren.
flow2k
1
@ flow2k, das ist der Link zu don_cristis Antwort.
Stéphane Chazelas
Ah, ich sehe es auf meinem Mac, aber schade, dass es weder auf RHEL noch auf Ubuntu ist. Vielen Dank.
flow2k
138

Beachten Sie, dass die kürzlich (Juni 2013) veröffentlichte Option "--keep (-k) für die Konsistenz mit Tools wie xz, lzip und bzip2 akzeptiert. Mit dieser Option entfernt gzip beim Komprimieren oder Dekomprimieren keine benannten Eingabedateien mehr" .gzip-1.6

Auszug aus der Manpage:

  -k --keep
         Keep (don't delete) input files during compression or decompression.

Ab 1.6jetzt können Sie die Originaldatei mit -koder --keepbehalten:

gzip -k -- "$file"

(Beachten Sie, dass es nicht funktioniert, wenn $fileist -(was gzipals stdin anstelle der eigentlichen aufgerufenen Datei interpretiert wird -). In diesem Fall müssen Sie es auf ändern. ./-)

Diese Option wurde erstmals in der FreeBSD-Implementierung vongzip (in FreeBSD 7.0 im Jahr 2007) eingeführt, um die Konsistenz zu gewährleisten bzip2. Das gzipbasiert auf einer Neufassung von GNU gzipdurch NetBSD. Die -kOption schaffte es 2010 schließlich zurück zu NetBSD .

don_crissti
quelle
10
Meine Güte. RHEL6 kommt nur mit Reißverschluss 1.3.12 in der Basis ...
Nicholas Tolley Cottrell
Dies funktioniert unter Mac / OS X :) (das ist BSD)
Paul
Gibt es viele Standard-Distributionen, die nicht mehr> = 1.6 verwenden? Ich
frage
Wofür ist "-"? Ich denke, gzip -k "Datei" funktioniert gut.
notilas
3
@notilas siehe unix.stackexchange.com/q/11376/22142
don_crissti
30

Aus der Dokumentation geht hervor, dass es keine Möglichkeit gibt, eine Kopie der Datei zu erstellen.

Sie können eine Shell-Funktion definieren

gzipkeep() {
    if [ -f "$1" ] ; then
        gzip -c -- "$1" > "$1.gz"
    fi
}

und dann

gzipkeep file.txt
Matteo
quelle
2
Beachten Sie, dass Sie die Datei, wenn sie ist -, als aufrufen müssen gzipkeep ./-.
Stéphane Chazelas