gzip: nén tệp trên Linux, giải nén gzip, cách dùng gunzip và zcat
gzip là lệnh Linux nén một tệp thành tệp .gz; để giải nén, bạn thêm -d vào cùng lệnh hoặc dùng gunzip. Trên máy chủ AlmaLinux 9, một tệp nhật ký truy cập 31.878 byte giảm còn 4.424 byte sau khi nén, và khi giải nén thì kích thước cùng thời gian sửa đổi ban đầu được trả lại nguyên vẹn.
Kết quả bên dưới được chạy trong một thư mục thử nghiệm trên máy chủ AlmaLinux 9.8 bằng tài khoản root, thời gian tính theo UTC. Nhật ký truy cập, ghi chú và tệp cấu hình là các tệp mẫu tạo ra để thử nghiệm, và địa chỉ IP trong nhật ký cũng là giá trị mẫu dùng cho tài liệu.
1️⃣ Cách dùng lệnh gzip
Thư mục thử nghiệm có hai nhật ký truy cập, hai tệp ghi chú, thư mục config chứa tệp cấu hình và thư mục restore trống.
ls -ltotal 88
-rw-r--r-- 1 root root 31878 Oct 28 23:50 access.log
-rw-r--r-- 1 root root 47748 Oct 27 23:59 access.log-20261027
drwxr-xr-x 2 root root 39 Oct 29 00:19 config
-rw-r--r-- 1 root root 45 Oct 28 14:30 memo.txt
-rw-r--r-- 1 root root 426 Oct 27 09:10 readme.txt
drwxr-xr-x 2 root root 6 Oct 29 00:19 restoreKhi bạn ghi tên tệp sau gzip, tệp đó biến thành tệp nén có thêm .gz ở cuối tên. Lệnh bên dưới nén access.log và không in gì khi chạy xong.
gzip access.logSau khi nén, ls -l không còn access.log mà chỉ còn access.log.gz. Nhật ký 31.878 byte đã thành 4.424 byte, và thời gian sửa đổi vẫn là thời gian của tệp gốc.
ls -l access.log access.log.gzls: cannot access 'access.log': No such file or directory
-rw-r--r-- 1 root root 4424 Oct 28 23:50 access.log.gzKhi thêm -v, gzip hiển thị tỉ lệ giảm và tên tệp mới cho từng tệp. [81.5%] ở dòng readme.txt là mức giảm so với kích thước gốc, còn [replaced with] nghĩa là tệp gốc đã được thay bằng tệp .gz.
gzip -v readme.txtreadme.txt: 81.5% -- replaced with readme.txt.gzĐể giữ tệp gốc, hãy thêm -k. Khi nén memo.txt với -k, memo.txt và memo.txt.gz nằm cạnh nhau.
gzip -k memo.txtls -l memo.txt memo.txt.gz-rw-r--r-- 1 root root 45 Oct 28 14:30 memo.txt
-rw-r--r-- 1 root root 71 Oct 28 14:30 memo.txt.gzmemo.txt 45 byte sau khi nén lại lớn lên thành 71 byte. Theo hướng dẫn chính thức, gzip vẫn nén dù kết quả lớn hơn tệp gốc, và lưu tên cùng thời gian của tệp gốc bên trong tệp nén.
Nếu ghi nhiều tệp cùng lúc, mỗi tệp sẽ có một tệp .gz riêng. Nén hai tệp cấu hình trong thư mục config sẽ cho hai tệp là app.conf.gz và site.conf.gz.
gzip -v config/app.conf config/site.confconfig/app.conf: 78.7% -- replaced with config/app.conf.gz
config/site.conf: 87.7% -- replaced with config/site.conf.gzls -l config/total 8
-rw-r--r-- 1 root root 206 Oct 20 11:00 app.conf.gz
-rw-r--r-- 1 root root 93 Oct 20 11:05 site.conf.gz2️⃣ Giải nén gzip
Khi giải nén access.log.gz bằng -d, không có gì được in ra, access.log xuất hiện lại và access.log.gz không còn.
gzip -d access.log.gzls -l access.log access.log.gzls: cannot access 'access.log.gz': No such file or directory
-rw-r--r-- 1 root root 31878 Oct 28 23:50 access.logaccess.log được khôi phục có kích thước 31.878 byte, và thời gian sửa đổi vẫn là Oct 28 23:50 như trước khi nén.
gunzip làm cùng việc với gzip -d. Khi thêm -k, nó giải nén mà vẫn giữ tệp nén, và [created] ở dòng -v nghĩa là đã tạo tệp mới mà không xóa tệp .gz.
gunzip -kv readme.txt.gzreadme.txt.gz: 81.5% -- created readme.txtls -l readme.txt readme.txt.gz-rw-r--r-- 1 root root 426 Oct 27 09:10 readme.txt
-rw-r--r-- 1 root root 108 Oct 27 09:10 readme.txt.gzgzip không có tùy chọn chọn thư mục đích, nên để giải nén sang thư mục khác, bạn dùng -c để đưa nội dung đã giải nén ra đầu ra chuẩn rồi ghi đường dẫn tệp mới sau [>]. Lệnh bên dưới giải nén memo.txt.gz thành memo.txt trong thư mục restore.
gzip -dc memo.txt.gz > restore/memo.txtls -l restore/total 4
-rw-r--r-- 1 root root 45 Oct 29 00:19 memo.txtKhi giải nén bằng -c, memo.txt.gz vẫn còn nguyên. restore/memo.txt mới có thời gian sửa đổi là Oct 29 00:19, lúc tệp được tạo.
3️⃣ Tùy chọn của lệnh gzip
-l in trên một dòng, không cần giải nén, kích thước sau nén, kích thước gốc, tỉ lệ giảm và tên tệp khi giải nén. Sau khi nén lại access.log bằng -k rồi kiểm tra bằng -l, kết quả như sau.
gzip -k access.loggzip -l access.log.gz compressed uncompressed ratio uncompressed_name
4424 31878 86.2% access.logKhi thêm -v, phía trước có thêm phương thức nén (defla, viết tắt của deflate), CRC của dữ liệu gốc và ngày giờ của tệp gốc.
gzip -lv access.log.gzmethod crc date time compressed uncompressed ratio uncompressed_name
defla b49b41c4 Oct 28 23:50 4424 31878 86.2% access.log-t chỉ kiểm tra tệp nén có bị hỏng không rồi kết thúc. Khi dùng cùng -v, [OK] xuất hiện sau mỗi tệp không có vấn đề.
gzip -tv access.log.gzaccess.log.gz: OKCác số từ -1 đến -9 là mức nén, và theo hướng dẫn chính thức giá trị mặc định là -6. Cùng một access.log được nén ba lần bằng -c rồi so sánh kích thước bằng wc -c.
gzip -c -1 access.log | wc -c5564gzip -c -6 access.log | wc -c4424gzip -c -9 access.log | wc -c4164| Mức nén | Kích thước .gz | So với kích thước gốc |
|---|---|---|
| Tệp gốc (access.log) | 31.878 byte | 100% |
| -1 (nhanh nhất) | 5.564 byte | 17.5% |
| -6 (mặc định) | 4.424 byte | 13.9% |
| -9 (nhỏ nhất) | 4.164 byte | 13.1% |
-9 nhỏ hơn mặc định 260 byte, còn -1 lớn hơn mặc định 1.140 byte.
Nếu chỉ ghi tên thư mục, [is a directory -- ignored] sẽ xuất hiện và thư mục bị bỏ qua.
gunzip configgzip: config is a directory -- ignoredĐể xử lý mọi tệp trong một thư mục, hãy thêm -r. Khi giải nén thư mục config, nơi hai tệp cấu hình đã được nén, bằng gunzip -r, hai tệp được giải nén lần lượt.
gunzip -rv configconfig/app.conf.gz: 78.7% -- replaced with config/app.conf
config/site.conf.gz: 87.7% -- replaced with config/site.confls -l config/total 8
-rw-r--r-- 1 root root 840 Oct 20 11:00 app.conf
-rw-r--r-- 1 root root 528 Oct 20 11:05 site.conf-r nén hoặc giải nén từng tệp trong thư mục riêng lẻ và không gộp nhiều tệp thành một. Để gộp cả thư mục thành một tệp nén, hãy dùng lệnh tar để vừa gộp vừa nén. Khi nén thư mục config bằng tar -czf, thư mục và hai tệp nằm gọn trong một config.tar.gz.
tar -czf config.tar.gz configtar -tzvf config.tar.gzdrwxr-xr-x root/root 0 2026-10-29 00:19 config/
-rw-r--r-- root/root 840 2026-10-20 11:00 config/app.conf
-rw-r--r-- root/root 528 2026-10-20 11:05 config/site.conf📌 Tùy chọn chính: kết quả chạy trong bài này
| Tùy chọn | Chức năng | Kết quả trong bài này | |
|---|---|---|---|
| -c | Đưa kết quả ra đầu ra chuẩn và giữ nguyên tệp gốc | Chuyển đầu ra của -dc vào restore/memo.txt thì tạo ra memo.txt 45 byte | |
| -d | Giải nén (giống gunzip) | access.log.gz biến mất và access.log 31878 byte trở lại | |
| -k | Giữ tệp gốc sau khi nén hoặc giải nén | memo.txt (45 byte) và memo.txt.gz (71 byte) nằm cạnh nhau | |
| -v | In tỉ lệ giảm và tên tệp mới cho từng tệp | readme.txt: 81.5% -- replaced with readme.txt.gz | |
| -l | In danh sách kích thước, tỉ lệ và tên khi giải nén của tệp nén | Kích thước sau nén 4424, kích thước gốc 31878, tỉ lệ 86.2%, tên access.log | |
| -t | Kiểm tra tệp nén có bị hỏng không | Với -tv, access.log.gz: OK, còn broken.gz bị cắt phần cuối cho unexpected end of file | |
| -r | Nén hoặc giải nén mọi tệp trong thư mục | Một lần gunzip -rv config giải nén cả config/app.conf.gz và config/site.conf.gz | |
| -f | Ghi đè mà không hỏi dù có tệp cùng tên | Bị ghi đè không hỏi: không còn memo.txt, chỉ còn memo.txt.gz (71 byte) | |
| -1 ~ -9 | Mức nén (-1 nhanh nhất, -9 nhỏ nhất, mặc định -6) | Đếm đầu ra nén bằng -1, -6, -9 với wc -c được 5564, 4424, 4164 |
📎 Tùy chọn khác: theo tài liệu hướng dẫn chính thức
| Tùy chọn | Chức năng | |
|---|---|---|
| -N | Khi nén thì lưu tên và thời gian của tệp gốc (mặc định khi nén), khi giải nén thì khôi phục tên và thời gian đã lưu | |
| -n | Khi nén không lưu tên và thời gian của tệp gốc, khi giải nén dùng tên đã bỏ .gz (mặc định khi giải nén) | |
| -q | Không in bất kỳ cảnh báo nào | |
| -S hậu tố | Nén với hậu tố chỉ định thay cho .gz, và khi giải nén thì tìm hậu tố đó trước | |
| --rsyncable | Nén sao cho khi đồng bộ tệp nén với máy chủ khác bằng rsync thì chỉ gửi phần thay đổi |
🔲 Trình mô phỏng lệnh gzip
Trong trình mô phỏng bên dưới, bạn có thể tự gõ lệnh để nén bằng gzip, giải nén và xem nội dung bằng zcat và zgrep.
4️⃣ Xem nội dung tệp gzip
Các nhật ký cũ được lưu kèm ngày sẽ chiếm ít dung lượng hơn nếu nén bằng gzip. Lệnh bên dưới nén access.log-20261027, nhật ký của ngày hôm trước.
gzip access.log-20261027Nhật ký đã nén có thể in ra màn hình bằng zcat mà không cần giải nén. zcat giống lệnh gunzip -c (theo hướng dẫn chính thức), nên tệp .gz vẫn còn nguyên.
zcat access.log-20261027.gz | head -3192.0.2.50 - - [27/Oct/2026:00:00:00 +0000] GET / HTTP/1.1 200 15929
192.0.2.54 - - [27/Oct/2026:00:00:07 +0000] GET / HTTP/1.1 200 17699
192.0.2.4 - - [27/Oct/2026:00:00:14 +0000] GET / HTTP/1.1 200 13813Đầu ra của zcat có thể chuyển sang lệnh khác qua pipe, và đếm bằng wc -l thì nhật ký này có 600 dòng.
zcat access.log-20261027.gz | wc -l600Để tìm một chuỗi cụ thể trong nhật ký đã nén, hãy dùng zgrep. Khi thêm -c, chỉ hiện số dòng có chứa [ 404 ]; để xem nội dung dòng, hãy chạy không có -c.
zgrep -c ' 404 ' access.log-20261027.gz37zgrep ' 404 ' access.log-20261027.gz | head -3192.0.2.23 - - [27/Oct/2026:00:02:06 +0000] GET /old-page-6/ HTTP/1.1 404 229
192.0.2.38 - - [27/Oct/2026:00:04:40 +0000] GET /old-page-2/ HTTP/1.1 404 217
192.0.2.22 - - [27/Oct/2026:00:07:42 +0000] GET /old-page-6/ HTTP/1.1 404 414Khi zcat nhận tệp chưa nén, nó in [not in gzip format] rồi dừng.
zcat access.log | head -1
gzip: access.log: not in gzip formatzgrep cũng đọc nguyên tệp chưa nén, nên bạn có thể tìm cùng lúc trong nhật ký đang dùng và các nhật ký cũ đã nén. Nếu ghi từ hai tệp trở lên, tên tệp sẽ đứng trước số dòng.
zgrep -c wp-login.php access.log access.log-20261027.gzaccess.log:36
access.log-20261027.gz:525️⃣ Lỗi gzip
Nếu nén lại một tệp đã có đuôi .gz, [already has .gz suffix -- unchanged] sẽ xuất hiện và tệp được giữ nguyên.
gzip access.log.gzgzip: access.log.gz already has .gz suffix -- unchangedNgược lại, nếu giải nén bằng -d một tệp không có đuôi .gz, [unknown suffix -- ignored] sẽ xuất hiện.
gzip -d memo.txtgzip: memo.txt: unknown suffix -- ignoredTệp chỉ có tên đuôi .gz nhưng không được nén bằng gzip sẽ kết thúc với [not in gzip format]. Thông báo này xuất hiện khi sao chép tệp văn bản memo.txt thành tên notgzip.gz rồi giải nén.
cp memo.txt notgzip.gzgzip -d notgzip.gz
gzip: notgzip.gz: not in gzip formatTệp .gz bị mất phần cuối do tải xuống bị ngắt sẽ kết thúc với [unexpected end of file]. Đây là kết quả kiểm tra bằng -t với broken.gz, tệp chỉ giữ lại 2.000 byte đầu của một nhật ký cũ đã nén.
head -c 2000 access.log-20261027.gz > broken.gzgzip -t broken.gz
gzip: broken.gz: unexpected end of fileNgay cả với tệp bị cắt, giải nén bằng zcat vẫn lấy ra được nội dung đến trước chỗ bị cắt. Từ nhật ký 600 dòng, 162 dòng còn lại trong restore/broken.log, và hướng dẫn chính thức cũng khuyên dùng zcat để cứu phần đầu của tệp nén bị hỏng.
zcat broken.gz > restore/broken.logwc -l restore/broken.log
gzip: broken.gz: unexpected end of file
162 restore/broken.logNếu đã có tệp cùng tên với tệp .gz sắp tạo, gzip sẽ hỏi có ghi đè không. Gõ n thì lệnh kết thúc với [not overwritten] và không thay đổi gì.
gzip memo.txtgzip: memo.txt.gz already exists; do you wish to overwrite (y or n)? n
not overwrittenKhi thêm -f, gzip ghi đè ngay mà không hỏi. Vì không thêm -k, memo.txt biến mất và chỉ còn memo.txt.gz.
gzip -f memo.txtls -l memo.txt memo.txt.gzls: cannot access 'memo.txt': No such file or directory
-rw-r--r-- 1 root root 71 Oct 28 14:30 memo.txt.gzCác thông báo lỗi gặp khi làm việc với nén và điều cần kiểm tra tiếp theo như sau.
| Đầu ra | Ý nghĩa | Việc cần kiểm tra tiếp |
|---|---|---|
| already has .gz suffix -- unchanged | Tệp đã có đuôi .gz nên không nén lại | Đã ghi tên tệp gốc cần nén chưa |
| unknown suffix -- ignored | Cố giải nén tệp không có đuôi .gz | Tên tệp .gz bằng ls |
| not in gzip format | Tên có đuôi .gz nhưng không phải tệp nén bằng gzip | Định dạng thật (zip, tar) và lệnh phù hợp |
| unexpected end of file | Phần cuối tệp nén bị cắt | So kích thước với tệp gốc rồi tải lại · cứu phần đầu bằng zcat |
| already exists; do you wish to overwrite | Đã có tệp cùng tên với tệp sắp tạo | y hoặc -f nếu được ghi đè · -c với tên khác để giữ lại |
| is a directory -- ignored | Ghi tên thư mục thay vì tệp | -r cho các tệp trong thư mục · tar để gộp thành một |
🔢 FAQ & nội dung đề xuất
Tìm kiếm
Lệnh grep trên Linux
Lệnh grep để tìm chuỗi trong tệp văn bản như nhật ký, kèm ví dụ nối với tail và find qua pipe.
Ổ đĩa
Lệnh du: kiểm tra dung lượng đĩa của tệp
Lệnh du để kiểm tra tệp và thư mục chiếm bao nhiêu dung lượng đĩa.
Xem tệp
Lệnh head và lệnh tail trên Linux
Lệnh head và tail để xem các dòng đầu và cuối của tệp, thường dùng khi kiểm tra nhật ký truy cập máy chủ.
ℹ️ Thông báo tiếp thị liên kết
Nội dung trên trang này có chứa liên kết affiliate (tiếp thị liên kết). Khi khách truy cập mua sản phẩm hoặc dịch vụ qua các liên kết này, trang sẽ nhận hoa hồng từ bên bán. Trong quá trình đó, số tiền người mua phải trả (sẽ giảm khi có chương trình khuyến mãi ↓) không hề tăng lên. Giá, khuyến mãi và tình trạng hàng được đăng theo thời điểm viết bài và có thể khác với thực tế, vì vậy hãy kiểm tra lại lần cuối với bên bán trước khi mua. Việc chọn và đánh giá sản phẩm dựa trên tiêu chí riêng của trang; việc có nhận hoa hồng hay không không ảnh hưởng đến thứ tự giới thiệu hay nội dung đánh giá.