gzip alle Dateien ohne sie zu löschen

11

Ich muss alle Dateien in einem Verzeichnis separat gzipen, einschließlich aller Dateien in Unterverzeichnissen, ohne die Originale danach zu löschen. Nehmen wir also an, ich habe index.html, ich möchte am Ende index.html.gzip UND index.html haben.

Ich kann alle Dateien in meinem Verzeichnis über gzip

gzip -r .

Aber ich möchte auch die Originaldateien behalten.

Ist das möglich?


quelle

Antworten:

9
find . -type f | \
while read -r x
do
  gzip -c "$x" > "$x.gz"
done

Das -cschiebt das Ergebnis auf stdout und hält das Original in Ruhe. Der Nachteil ist, dass Sie die Dateien selbst finden müssen. Für ein komplexeres Durchlaufen können Sie find(1)jedoch Folgendes verwenden: .Suchen ab dem aktuellen Verzeichnis und -type fRückgabe des Namens jeder regulären Datei.

Boldewyn
quelle
Warum *.*in ls?
@pooh: Entspricht *.*allen regelmäßig benannten Dateien und normalerweise keinen Verzeichnissen. Natürlich funktioniert es nur in den meisten Fällen und normalerweise nicht, wenn Sie es brauchen. Verwenden Sie dann den findBefehl.
Boldewyn
@ Boldewyn: Die Frage war, alle Dateien in einem Verzeichnis zu gzipen. ls *.*wählt keine Dateien wie TODO aus .
lsist nicht erforderlich überhaupt : for x in *. Die Verwendung findsollte jedoch sein find . -type f | while read -r x.
Bis auf weiteres angehalten.
Antwort aktualisiert. Danke für das -rEinschalten read.
Boldewyn
5
find . -type f -not \( -name '*.gz' -or -name '*[~#]' \) -exec sh -c 'gzip -c "{}" > "{}.gz"' \;

Sie können es einfach umschalten, um einzuschließen, was Sie komprimieren möchten ( -name '*.txt -or -name '*.htmlusw.), anstatt wie jetzt, mit Ausnahme einiger Dateien (bereits komprimierte, Backup- und temporäre Dateien).

Behandelt auch Leerzeichen im Dateinamen.

Wechsel gzipauf echo gzipzum Testen. Oder überspringen Sie den -exec-Teil alle zusammen.

Edit: Oh, ich habe vergessen zu erwähnen, dass dies nicht prüft, ob es <target>.gzbereits existiert. Dies kann ein Problem sein oder auch nicht.

Edit2: Ok, hier geht es mit etwas, das nach vorhandenen Dateien sucht . Wenn das gewünscht sein mag. Verzeihen Sie die Oneliney-Ness.

while read file; do if [ ! -f "$file.gz" ]; then echo "Compressing $file"; gzip -c "$file" > "$file.gz"; else echo "Not overwriting $file.gz";  fi  done < <(find . -type f -not \( -name '*.gz' -or -name '*[~#]' \))

Mein find-foo ist vielleicht nicht das, was es sein könnte, es kann sehr gut möglich sein, direkt in find zu überspringen.

Plundra
quelle
1
Lesen Sie einfach, dass -name vor -type stehen sollte, um zu vermeiden, dass stat für jede Datei aufgerufen wird.
@ Ben Sinnvoll, gute Eingabe! Bei großen Bäumen kann dies auffallen.
Plundra
2

Fügen Sie einfach die Option -c hinzu. Ich denke, das sollte funktionieren

Ken Wayne VanderLinde
quelle
1
Dies funktioniert wahrscheinlich nur, wenn jeweils nur eine Datei komprimiert wird.
its_me
0
gzip -rc `ls` > archive.gz

Getestet auf Debian (gzip 1.3.12-6)

tannerli
quelle
Das schafft ein Archiv. Das OP will separate Archive. lsist unnötig, verwenden *.
Bis auf weiteres angehalten.