Gzip - standard kompersji w Linuksie

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/

gzip-cover

desktop linux polecenia serwer terminal