Chciałbym skompresować plik tekstowy za pomocą narzędzia wiersza poleceń gzip, jednocześnie zachowując oryginalny plik. Domyślnie uruchomienie następującego polecenia
gzip file.txt
powoduje modyfikację tego pliku i zmianę jego nazwy file.txt.gz
. zamiast tego chciałbym mieć ten nowy skompresowany plik w dodaniu do istniejącego file.txt
. Na razie używam następującego polecenia, aby to zrobić
gzip -c file.txt > file.txt.gz
Działa, ale zastanawiam się, dlaczego nie ma prostszego rozwiązania do wykonania tak powszechnego zadania? Może przegapiłem tę opcję?
Komentarze
- Dzieje się 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 nakazuje programowi gzip zapisanie go pod inną nazwą. To ' dlaczego to działa
- @SHW Nie ' nie dostałem twojego komentarza …?
- @ManuelSelva Po skompresowaniu oryginalnego pliku ' nie jest już potrzebny, myślę, że taki był projekt.
- Dlaczego gzip / gunzip zrób to domyślnie , gdy żadne inne narzędzie uniksowe tego nie robi jest poza mną.
Odpowiedz
GNU gzip
1.6 lub nowszy, FreeBSD i pochodne lub najnowsze wersje NetBSD, patrz don_cristi ”.
W każdej wersji możesz używać przekierowań powłoki, jak w:
gzip < file > file.gz
Jeśli nie podano dowolny argument, gzip
czyta swoje standardowe wejście, kompresuje je i zapisuje skompresowaną wersję na standardowe wyjście. Jako bonus, używając przekierowań powłoki, nie musisz martwić się o pliki o nazwie "--help"
lub "-"
(ten ostatni nadal jest problemem dla gzip -c --
).
Kolejną korzyścią w porównaniu z gzip -c file > file.gz
jest to, że file
nie można otworzyć, polecenie zakończy się niepowodzeniem bez utworzenia pustego file.gz
(lub nadpisania istniejącego file.gz
) i bez uruchamiania gzip
w ogóle.
Istotna różnica w porównaniu z gzip -k
polega jednak na tym, że nie będzie próby kopiowanie metadanych file
„(własność, uprawnienia, czas modyfikacji, nazwa nieskompresowanego pliku) do file.gz
.
Również jeśli file.gz
już istniał, po cichu zastąpi go, chyba że włączyłeś opcję noclobber
w powłoce (z set -o noclobber
na przykład w powłokach POSIX).
Komentarze
- Teraz dotyczy to specyfiki OP ' pytanie i odpowiedzi na ge Podstawowe pytanie " Jak powiedzieć programowi gzip, aby zachował oryginalny plik ". Bardzo poręczny i bardziej przydatny niż
-c
. - Pamiętaj, że < i > powinny być faktycznie wpisane do polecenia i nie stanowią symbolu zastępczego dla nazwy pliku
- Co ' jest
-k
? Nie można go ' znaleźć na stronach podręcznika, np. ta wersja tutaj linux.die.net/man/1/gzip . Wygląda też na to, że program gzip domyślnie kopiuje metadane pliku '. - @ flow2k, że ' s link do odpowiedzi don_cristi '.
- @St é phaneChazelas Działa również na gzip w wersji 1.4.
cat file | gzip > file.gz
Odpowiedź
Zwróć uwagę, że ostatnio (czerwiec 2013 ) wydany gzip-1.6
" akceptuje –keep (-k) opcja, dla 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 " .
Fragment strony podręcznika:
-k --keep Keep (don"t delete) input files during compression or decompression.
Tak więc od 1.6
możesz użyć -k
lub --keep
aby zachować oryginalny plik:
gzip -k -- "$file"
(zwróć uwagę, że nie działa, jeśli $file
to -
(co gzip
interpretuje jako oznaczające stdin zamiast rzeczywistego pliku o nazwie -
), w takim przypadku musisz zmienić ją na ./-
)
Ta opcja to po raz pierwszy wprowadzony we FreeBSD implementacji gzip
(w FreeBSD 7.0 w 2007 r.) w celu zachowania spójności z bzip2
. To gzip
jest oparty na przepisaniu GNU gzip
przez NetBSD. -k
ostatecznie powrócił do NetBSD w 2010 roku .
Komentarze
- Rany. RHEL6 jest dostarczany tylko z zipem 1.3.12 w bazie …
- Działa to na Mac / OS X 🙂 (czyli BSD)
- Czy jest wiele standardowych dystrybucji nie używających > = 1.6 już? Zastanawiasz się, czy odpowiedź wymaga aktualizacji
- Do czego służy " – "? Myślę, że plik gzip -k " " działa dobrze.
- @notilas patrz unix.stackexchange.com/q/11376/22142
Odpowiedź
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 }
a następnie
gzipkeep file.txt
Komentarze
- Zwróć uwagę, że jeśli plik jest
-
, musisz nazwać gogzipkeep ./-
. - To najlepsze rozwiązanie dla skryptów IMO, ponieważ możesz być pewien, że plik wyjściowy
> "$1.gz"
będzie istnieć dokładnie tak, jak określono. Ponadto możesz również określić inną nazwę, jeśli zajdzie taka potrzeba.