Bagaimana cara membuat file gzip tanpa ekstensi file .gz?

14

Saya ingin membuat file gzip yang mempertahankan nama file asli. Misalnya gzipping "example.txt" harus menampilkan file gzipped bernama "example.txt" daripada "example.txt.gz." Apakah mungkin untuk melakukan ini secara elegan dengan satu perintah (tidak melakukan yang berikutnya mv)?

jamieb
sumber
4
Saya sedikit penasaran. Mengapa kamu menginginkan ini? Kedengarannya seperti ide yang buruk.
Bernhard
3
Ya. Anda menempatkan 2 baris penuh dalam skrip bash dan menyebutnya "my-elegant-command". ;)
goldilocks
2
@Bernhard Ini adalah bagian dari proses pembangunan integrasi berkelanjutan untuk aplikasi web. Aset statis (file CSS, JS) perlu dikompresi tanpa mengubah nama file. Saat dikirimkan ke browser, tajuk "pengkodean konten: gzip" disertakan sehingga ekstensi tidak relevan. Tetapi jika nama file diubah, saya harus melakukan pencarian-dan-ganti dalam file HTML sumber.
jamieb
Jika ini benar-benar masalah bagi Anda, Anda bisa mendefinisikan fungsi bash yang meneruskan $ * ke gzip yang dapat dieksekusi dan baris kedua melakukan mv untuk Anda.
Bratchley
4
@ masalah aplikasi web Anda: server web yang layak dapat / akan melakukan kompresi untuk Anda ...
Bananguin

Jawaban:

12

Ini tidak bekerja:

# echo Hello World > example.txt
# gzip < example.txt > example.txt # WRONG!
# file example.txt
example.txt: gzip compressed data, from Unix, last modified: Thu Mar 21 19:45:29 2013
# gunzip < example.txt
<empty file>

Ini adalah kondisi lomba:

# echo Hello World > example.txt
# dd if=example.txt | gzip | dd of=example.txt # still WRONG!
# gunzip < example.txt 
Hello World # may also be empty

Masalahnya adalah bahwa > example.txt(atau dd of=example.txtdalam hal ini) membunuh file sebelum proses lain memiliki kesempatan untuk membacanya. Jadi tidak ada solusi yang jelas, itu sebabnya Anda harus tetap berpegang pada mv.

Ada beberapa cara Anda bisa menipu. Anda dapat membuka file tersebut, kemudian memutuskan tautannya - file tersebut akan terus ada hingga Anda menutupnya - dan kemudian membuat file baru dengan nama yang sama dan menulis data yang di-gzip ke situ. Namun saya tidak tahu cara yang jelas untuk memaksa bash menggunakan itu, dan bahkan jika saya melakukannya, jawaban saya tetap akan:

Jangan lakukan itu.

Jika gzipgagal karena alasan apa pun, atau masalah apa pun terjadi, seperti Anda kehabisan ruang saat gzipping (karena proses lain sedang menulis, atau hasil gzip lebih besar dari input - yang terjadi untuk data acak - dll.), Anda baru saja kehilangan file Anda . Selamat!

Buat file terpisah dan mvsukses. Itu adalah metode paling sederhana, mudah dimengerti, dan paling dapat diandalkan yang pernah Anda temukan.

frostschutz
sumber
1
Bagaimana kalau menambahkan demi kelengkapan:gzip example.txt && mv example.txt.gz example.txt
depquid
2
Tidak ada depquid yang membaca OP - itu tidak valid .
goldilocks
@goldilocks "Buat file terpisah dan mvsukses." dapat dibuat lebih elegan? Saya hanya mencoba mengusulkan agar jawaban frostschutz ditambah dengan contoh spesifik. Jika mvbisa digunakan lebih elegan dari yang saya kira, tolong beri contoh.
depquid
Saran Anda adalah pendekatan yang sederhana, elegan, jelas, tetapi apakah itu berhasil tergantung pada begitu banyak variabel, misalnya apa yang Anda lakukan jika sudah ada contoh.txt.gz? Juga tanpa ekstensi untuk bekerja, Anda harus mencegah gzipping file yang sudah gzip. Itu adalah kaleng cacing yang sama sekali baru, tetapi itu bukan bagian dari pertanyaan.
frostschutz
10

Saya memiliki masalah yang sama, sebagai bagian dari penyebaran CI ke AWS S3.

Ini adalah apa yang saya lakukan untuk secara gzip mencari direktori (di tempat) tanpa .gzakhiran:

find . -type f -exec gzip "{}" \; -exec mv "{}.gz" "{}" \;

Tampaknya cukup bersih untukku. Tapi ya sepertinya Anda perlu mvdi sana di suatu tempat.

Jika Anda menggunakan, gruntAnda bisa melihatnya grunt-contrib-compress. Beberapa gruntalat khusus untuk digunakan ke S3 akan menangani gzip juga untuk Anda.

tobek
sumber
1
sebaiknya find . -type ...jangan find.tambahkan spasi :)
Humdinger
2

-S ekstensi yang Anda inginkan

gzip -S "`_date +%Y_%M' dog.txt 

akan menghasilkan dog.txt_2015_11

ketika Anda unzip, Anda harus menentukan ekstensi.

gzip -d _2015_11 dog.txt_2015_11

Di unix gunakan perintah file untuk menentukan jenis file apa yang Anda miliki, ekstensi itu menyesatkan, atau sering hilang.

pengguna143758
sumber
1

Saya tidak berpikir membuat file gzip tanpa ekstensi benar-benar hal yang tepat untuk dilakukan.

IMHo Anda harus mengkonfigurasi server web Anda untuk membaca file .gz. Anda mungkin sudah memiliki aturan seperti ini:

Path asets/:
  If header Accept-Encoding contains "gzip" and not contains "gzip;q=0":
    Add header Content-Encoding: gzip

Anda hanya perlu menambahkan aturan penulisan ulang nama file yang diminta untuk menambahkan ".gz" (sebenarnya, Anda harus memeriksa apakah file tersebut ada, sama seperti Anda harus memverifikasi bahwa klien memang membuat daftar gzip pada header Terima-Pengkodean)

Malaikat
sumber
1

Anda dapat mencoba s3_website untuk ini.

Saya tidak suka fakta itu ditulis dalam scala dan ruby ​​dan itu membutuhkan JVM. Saya juga tidak suka asumsi yang dibuatnya (terutama fakta bahwa ia menghapus file tambahan dari bucket) tetapi itu akan berfungsi jika Anda baik-baik saja dengan itu.

Saya berencana untuk menulis alat seperti itu sendiri yang tidak memiliki batasan ini, tetap disini.

Cristian Măgherușan-Stanciu
sumber
0

Ini sebenarnya bukan sesuatu yang harus Anda lakukan, terutama karena ketika mentransfer file ini ke sistem atau orang lain, itu mungkin akan membingungkan mereka dan tidak menemukannya sebagai file terkompresi.

Jika Anda tidak ingin menggunakan akhiran apa pun, maka GNU tidak baik untuk Anda, karena gzip -S ""akan mengembalikan a gzip: invalid suffix ''.

Namun, Anda selalu dapat mengirim sesuatu seperti gzip -S " "(ruang kosong), dan itu akan ditampilkan seperti ini:

$ file testfile\  
testfile: gzip compressed data, was "testfile", from Unix, last modified: Tue Jun  3 XX:XX:XX 2014

Setelah itu, jika Anda ingin mendekompresnya, Anda harus melakukan sesuatu seperti gunzip -c testfile\ (tanpa menentukan akhiran), atau bahkan dengan -fflag.

Saya dengan tulus berpikir bahwa menambahkan mvperintah dengan &&tidak akan membuat banyak masalah pada kode Anda. Ngomong-ngomong, dan seperti yang dikatakan @frostschutz, bukan ide yang bagus untuk melakukan ini.

AleksanderKseniya
sumber
Ini adalah sesuatu yang diperlukan jika Anda ingin menggunakan S3 untuk menyajikan file terkompresi, seperti untuk hosting situs web statis. Anda dapat mempertimbangkan ini: github.com/laurilehmijoki/s3_website
Cristian Măgherușan-Stanciu