Jak powiedzieć gzip, aby zachował oryginalny plik?


210

Chciałbym skompresować plik tekstowy za pomocą narzędzia wiersza polecenia gzip, zachowując oryginalny plik. Domyślnie uruchamiane jest następujące polecenie

gzip file.txt

powoduje modyfikację tego pliku i zmianę jego nazwy file.txt.gz. zamiast tego zachowania chciałbym mieć ten nowy skompresowany plik oprócz istniejącego file.txt. Na razie używam do tego następującego polecenia

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

Działa, ale zastanawiam się, dlaczego nie ma łatwiejszego rozwiązania tak powszechnego zadania? Może przegapiłem opcję zrobienia tego?


3
Jest tak, ponieważ gzip kompresuje podany plik i tworzy nowy plik. Kompresja oznacza ściśnięcie oryginalnego pliku i zastąpienie go nowym. Twoja opcja „-c” wyraźnie mówi gzip, aby zapisał go pod inną nazwą. Właśnie dlatego to działa
SHW

@ SHW Nie dostałem twojego komentarza ...?
Manuel Selva

@ManuelSelva po skompresowaniu oryginalnego pliku nie jest już potrzebny, tak sądzę.
stokrotka

2
Dlaczego gzip / gunzip robi to domyślnie, skoro żadne inne narzędzie uniksowe nie robi tego poza mną.
Mateen Ulhaq

Odpowiedzi:


247

W przypadku GNU gzip1.6 lub nowszego, FreeBSD i pochodnych lub najnowszych wersji NetBSD, patrz odpowiedź don_cristi .

W każdej wersji możesz używać przekierowań powłoki jak w:

gzip < file > file.gz

Gdy nie podano żadnego argumentu, gzipodczytuje standardowe wejście, kompresuje je i zapisuje skompresowaną wersję na standardowe wyjście. Jako bonus, gdy korzystasz z przekierowań powłoki, nie musisz się martwić o wywołane pliki "--help"lub "-"(ten drugi problem nadal jest problemem gzip -c --).

Kolejną zaletą gzip -c file > file.gzjest to, że jeśli filenie można otworzyć, polecenie zakończy się niepowodzeniem bez utworzenia pustego file.gz(lub zastąpienia istniejącego file.gz) i bez uruchamiania gzip.

Istotna różnica w porównaniu z gzip -ktym, że nie będzie próby skopiowania filemetadanych (własność, uprawnienia, czas modyfikacji, nazwa nieskompresowanego pliku) do file.gz.

Również jeśli file.gzjuż istniał, po cichu zastąpi go, chyba że włączysz tę noclobberopcję w swojej powłoce ( set -o noclobberna przykład w powłokach POSIX).


4
Teraz dotyczy to szczegółów pytania OP i odpowiada na ogólne pytanie „Jak powiedzieć gzip, aby zachował oryginalny plik”. Bardzo przydatny i bardziej przydatny niż -c.
kodewaggle 18.12.12

8
Zauważ, że <i> powinny być wpisane do polecenia i nie reprezentują symbolu zastępczego dla nazwy pliku
Gaurav Gupta

Jaka jest -kopcja Nie można go znaleźć na stronach podręcznika man, np. Ta wersja tutaj linux.die.net/man/1/gzip . Wygląda na to, że gzip domyślnie kopiuje metadane pliku.
flow2k

1
@ flow2k, to jest link do odpowiedzi don_cristi.
Stéphane Chazelas

ah, widzę to na moich makach, ale szkoda, że ​​nie ma RHEL ani Ubuntu. Dzięki.
flow2k

138

Zauważ, że niedawno wydany (czerwiec 2013) „akceptuje opcję --keep (-k), dla zachowania spójności z narzędziami takimi jak xz, lzip i bzip2. Dzięki tej opcji gzip nie usuwa już nazwanych plików wejściowych podczas kompresji lub dekompresji” .gzip-1.6

Fragment strony man:

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

Od tego momentu 1.6możesz użyć -klub --keepzachować oryginalny plik:

gzip -k -- "$file"

(zwróć uwagę, że nie działa, jeśli $filejest -(co gzipinterpretuje jako oznaczające standardowe wejście zamiast rzeczywistego wywołanego pliku -), w takim przypadku musisz go zmienić na ./-)

Ta opcja została pogzip raz pierwszy wprowadzona w implementacji FreeBSD (w FreeBSD 7.0 w 2007 r.) W celu zachowania spójności z bzip2. Który gzipopiera się na przepisanie GNU gzipprzez NetBSD. -kOpcja w końcu się go z powrotem do NetBSD w 2010 roku .


10
Rany. RHEL6 pochodzi tylko z zamkiem 1.3.12 w bazie ...
Nicholas Tolley Cottrell,

Działa to na Mac / OS X :) (czyli BSD)
Paul

Czy istnieje wiele standardowych dystrybucji, które już nie używają> = 1.6? Zastanawiasz się, czy odpowiedź wymaga aktualizacji
MichaelChirico

Co jest dla? Myślę, że gzip -k „plik” działa dobrze.
notilas


30

Z dokumentacji wynika, że ​​nie ma opcji utworzenia kopii pliku.

Możesz zdefiniować funkcję powłoki

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

i wtedy

gzipkeep file.txt

2
Zauważ, że jeśli plik jest -, musisz nazwać go jako gzipkeep ./-.
Stéphane Chazelas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.