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ć go gzipkeep ./-.
  • 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.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *