gzip to popularny algorytm do kompresji danych, który zmniejsza wielkość plików przez kompresję bezstratną.
gzip to także polecenie i program zastępuje podany plik nowym z rozszerzeniem .gz. W systemach linuksowych razem z gzip dostępne są polecenia gunzip i zcat.
$ ls -l
-rw-rw-r-- 1 libran libran 1686941 Feb 8 09:13 NEWS
$ gzip NEWS
$ ls -l
-rw-rw-r-- 1 libran libran 604625 Feb 8 09:13 NEWS.gz
Plik .gz ma takie same tryby dostępu jak oryginalny plik.
Aby rozpakować skompresowany plik używamy polecenia gzip z przełącznikiem -d:
$ ls -l
-rw-rw-r-- 1 libran libran 604625 Feb 8 09:13 NEWS.gz
$ gzip -d NEWS.gz
$ ls -l
-rw-rw-r-- 1 libran libran 1686941 Feb 8 09:13 NEWS
Ten sam efekt rozpakowania można użyskać poleceniem gunzip:
$ ls -l
-rw-rw-r-- 1 libran libran 604625 Feb 8 09:13 NEWS.gz
$ gunzip NEWS.gz
$ ls -l
-rw-rw-r-- 1 libran libran 1686941 Feb 8 09:13 NEWS
gzip może operować na wielu plikach podanych jako argumenty, czy to jako jawne nazwy czy w postaci wzorca dopasowania:
$ ls -l
-rw-r--r-- 1 libran libran 1355283 Feb 8 09:33 HISTORY
-rw-rw-r-- 1 libran libran 1686941 Feb 8 09:13 NEWS
$ gzip NEWS HISTORY
$ ls -l
-rw-r--r-- 1 libran libran 494330 Feb 8 09:33 HISTORY.gz
-rw-rw-r-- 1 libran libran 604625 Feb 8 09:13 NEWS.gz
$ gzip -d *.gz
$ ls -l
-rw-r--r-- 1 libran libran 1355283 Feb 8 09:33 HISTORY
-rw-rw-r-- 1 libran libran 1686941 Feb 8 09:13 NEWS
Przy rozpakowaniu (gzip -d) posłużyliśmy się wzorcem *.gz który oznacza wszystkie pliki z rozszerzeniem .gz w bieżącym katalog. gzip rozpakował dwa pliki.
Domyślnie gzip usuwa oryginalny plik. Możemy jednak wymusić pozostawienie go za pomocą opcji -k (keep):
$ ls -l
-rw-rw-r-- 1 libran libran 1686941 Feb 8 09:13 NEWS
$ gzip -k NEWS
$ ls -l
-rw-rw-r-- 1 libran libran 1686941 Feb 8 09:13 NEWS
-rw-rw-r-- 1 libran libran 604625 Feb 8 09:13 NEWS.gz
gzip potrafi wyświetlić kilka podstawowy informacji o skompresowanym pliku. Służy do tego opcja -l, np:
$ gzip -l NEWS.gz
compressed uncompressed ratio uncompressed_name
604625 1686941 64.2% NEWS
Możemy zobaczyć jaki jest oryginalny rozmiar pliku, oryginalna nazwa (która nie musi być tą samą nazwą bez rozszerzenia .gz ), oraz stopień kompresji podany w procentach.
Stopień kompresji możemy też podejrzeć podczas tworzenia archiwum za pomocą opcji -v (verbose):
$ gzip -v NEWS
NEWS: 64.2% -- replaced with NEWS.gz
gzip posiada opcję -f (force) pozwalającą siłowo nadpisać istniejące pliki albo wykonać akcję, która pozornie nie ma sensu:
$ ls -l
-rw-r--r-- 1 libran libran 1686941 Feb 8 11:46 NEWS
-rw-r--r-- 1 libran libran 604625 Feb 8 11:46 NEWS.gz
$ gzip NEWS
gzip: NEWS.gz already exists; do you wish to overwrite (y or n)? n
not overwritten
$ ls -l
-rw-r--r-- 1 libran libran 1686941 Feb 8 11:46 NEWS
-rw-r--r-- 1 libran libran 604625 Feb 8 11:46 NEWS.gz
$ gzip -f NEWS
$ ls -l
-rw-r--r-- 1 libran libran 604625 Feb 8 11:46 NEWS.gz
Gdy docelowy plik już istnieje (NEWS.gz) gzip pyta czy go napisać. W przykładzie odrzucono tę możliwość (n). Pliki nie zostały zmienione. Z opcją -f plik NEWS został ponownie skompresowany, zapisany jako NEWS.gz, a oryginalny plik został usunięty.
gzip, podobnie jak wiele innych narzędzi w Linuksie, umożliwia pracę ze strumieniami danych na standardowym wejściu i wyjściu.
Służy do tego opcja -c, lub podanie jako nazwy pliku znaku - (minus). Nowsze wersje gzip odmawiając pracy jeśli standardowym wyjściem jest terminal. Można to ominąć za pomocą opcji -f:
$ gzip -c -f
Ala ma kota
s�IT�MT��/I����
W przykładnie gzip uruchomiony z opcją -c czeka na wprowadzenie danych. Wpisano tekst, następnie wciśnięto Ctrl+D aby zakończyć wejście. gzip wypisał skompresowane dane na terminal. Są to dane binarne, dlatego na terminalu pojawiają się "krzaczki".
Inny przykład pracy w trybie strumienia danych:
$ cat NEWS | gzip > NEWS.gz
$ ls -l
-rw-r--r-- 1 libran libran 1686941 Feb 8 11:46 NEWS
-rw-rw-r-- 1 libran libran 604620 Feb 8 12:20 NEWS.gz
Za pomocą polecenia cat wysyłamy zawartość pliku NEWS na standardowe wyjście. Za pomocą operatora potoku | przekazujemy te dane na standardowe wejście programu gzip. Gzip w tym trybie skompresowane dane także wypisuje na standardowe wyście, dla tego przekierowujemy ja za pomocą > do pliku NEWS.gz. Zauważmy, że oryginalny plik pozostaje tu nie zmieniony podobnie jak przy użyciu opcji -k.
Ten tryb pracy jest wykorzystywany przez wiele narzędzi w Linuksie do kompresji danych w locie. Przykładami takich narzędzi są tar, man.
Wykonajmy jeszcze jeden przykład:
$ echo "Ala ma konta" | gzip > ala.gz
$ ls -l ala.gz
-rw-rw-r-- 1 libran libran 33 Feb 8 12:30 ala.gz
Jak wspomnieliśmy poleceniu gzip towarzyszy dodatkowe polecenie zcat. Służy ono do wypisania zwartości skompresowanego pliku na standardowe wyjście.
$ zcat ala.gz
Ala ma konta
$ ls -l ala.gz
-rw-rw-r-- 1 libran libran 33 Feb 8 12:30 ala.gz
Zawartość pliku jest wypisana na terminal, a oryginalny pliku jest nienaruszony.
Podobne działania za pomocą samego gzip i gunzip:
gzip -d < ala.gz
Ala ma konta
$ ls -l ala.gz
-rw-rw-r-- 1 libran libran 33 Feb 8 12:30 ala.gz
$ cat ala.gz | gzip -d
Ala ma konta
libran@korba3:~/lmo/web/linuxownia/work/gzip
$ cat ala.gz | gunzip
Ala ma konta
W przypadku niewielkich plików gzip działa szybko i daje znaczący stopień
kompresji jeśli tylko dane daję się kompresować. Dla większych zbiorów danych
czas kompresji może być zauważalny a nawet nieakceptowanie długi. Również
stopień kompresji może mieć znaczenie gdy potrzeba oszczędzić większą
przestrzeń dyskową. Gzip pozwala regulować stopień kompresji danych kosztem
dłuższego czasu pracy. Służą do tego przełączniki liczbowe -1 () do -9 oraz
mnemotechniczne --fast (najszybszy ) i --best (największa kompresja)
$ gzip -1 NEWS
$ ls -l
-rw-r--r-- 1 libran libran 722069 Feb 8 11:46 NEWS.gz
$ gzip -9 NEWS
$ ls -l
-rw-r--r-- 1 libran libran 602310 Feb 8 11:46 NEWS.gz
$ gzip NEWS
$ ls -l NEWS.gz
-rw-r--r-- 1 libran libran 604625 Feb 8 11:46 NEWS.gz
W przykładzie kompresja z opcja -1 daje plik sporo większy, niż przy pracy domyślnej i opcji -9. Program stosuje domyślny zadany stopień kompresji -6 i w większości przypadków jest on zadowalającym kompromisem między prędkością działania i poziomem kompresji.
Warto wymienić jeszcze jedną funkcje - kompresję rekursywną katalogu - -r.
$ ls -lR dir
dir:
total 2064
drwxrwxr-x 2 libran libran 4096 Feb 8 13:05 a
drwxrwxr-x 2 libran libran 4096 Feb 8 13:05 b
-rw-rw-r-- 1 libran libran 1048576 Feb 8 13:05 file1
-rw-rw-r-- 1 libran libran 1048576 Feb 8 13:05 file2
dir/a:
total 1028
-rw-rw-r-- 1 libran libran 1048576 Feb 8 13:05 file3
dir/b:
total 1028
-rw-rw-r-- 1 libran libran 1048576 Feb 8 13:05 file4
$ gzip -vr dir/
dir/file1: -0.0% -- replaced with dir/file1.gz
dir/b/file4: -0.0% -- replaced with dir/b/file4.gz
dir/file2: -0.0% -- replaced with dir/file2.gz
dir/a/file3: -0.0% -- replaced with dir/a/file3.gz
$ ls -lR dir
dir:
total 2064
drwxrwxr-x 2 libran libran 4096 Feb 8 13:08 a
drwxrwxr-x 2 libran libran 4096 Feb 8 13:08 b
-rw-rw-r-- 1 libran libran 1048760 Feb 8 13:05 file1.gz
-rw-rw-r-- 1 libran libran 1048760 Feb 8 13:05 file2.gz
dir/a:
total 1028
-rw-rw-r-- 1 libran libran 1048760 Feb 8 13:05 file3.gz
dir/b:
total 1028
-rw-rw-r-- 1 libran libran 1048760 Feb 8 13:05 file4.gz
Zauważmy, że kompresja rekursywna katalogu w przypadku gzip oznacza skompresowania każdego pliku z osobna. gzip nie tworzy zbiorczych archiwów danych. Każdy skompresowany plik zawiera dokładnie jeden plik. Aby połączyć wiele plików we wspólne archiwum musimy użyć innego narzędzia, np. tar.
Wykonajmy jeszcze kilka eksperymentów z gzip.
Opcja -f pozwala wymusić kompresję na nawet już skompresowanego pliku:
$ gzip -f -v -k NEWS.gz
NEWS.gz: -0.0% -- created NEWS.gz.gz
$ gzip -f -v -k NEWS.gz.gz
NEWS.gz.gz: -0.0% -- created NEWS.gz.gz.gz
$ gzip -f -v -k NEWS.gz.gz.gz
NEWS.gz.gz.gz: -0.0% -- created NEWS.gz.gz.gz.gz
$ ls -l
-rw-rw-r-- 1 libran libran 604625 Feb 8 09:13 NEWS.gz
-rw-rw-r-- 1 libran libran 604746 Feb 8 09:13 NEWS.gz.gz
-rw-rw-r-- 1 libran libran 604870 Feb 8 09:13 NEWS.gz.gz.gz
-rw-rw-r-- 1 libran libran 604997 Feb 8 09:13 NEWS.gz.gz.gz.gz
Widzimy, że gzip za każdym razem dodaje kolejne rozszerzenie .gz. Jednak co ważniejsze, rozmiar pliku po ponownej kompresji, nieznacznie rośnie. Wynika to z faktu, że program do kompresji dodaje pewne niezbędne informacje o metadanych pliku, jak nazwa, tryby dostępu oraz sumy kontrolne.
Podsumowanie
gzip jest bardzo popularnym narzędziem kompresji danych w Linuksie. Mniej lub bardziej jawnie jest wykorzystywane przez serwery www, inne narzędzia do archiwizacji, dystrybucje do kompresji mnie używanych plików np. man, doc. Znajduje zastosowanie przy archiwizacji i wykonywaniu kopii zapasowych. Szczególnie użyteczny jest w połączeniu z tar. gzip może być zastępowany przez wydajniejsze algorytmy jak bzip xz, brotli. Warto tu wspomnieć o narzędziu pigz, które stosuje format plików zgodny z gzip, ale działa wielowątkowo, co pozwala znacząco skrócić czas kompresji na nowoczesnych procesorach. Tym nie mnie warto znać gzip, ze względu na jego popularność oraz pewien standard przełączników i opcji oraz współpracę z innymi narzędziami.
Omawiana jest tu implementaacja GNU gzip. Program ten jest objęty licencją wolnego oprogramowania GNU General Public License.
Strona domowa projektu: https://www.gnu.org/software/gzip/
