Як створити файл gzip без розширення .gz?


14

Я хотів би створити gzipped файл, який зберігає початкове ім'я файлу. Наприклад, gzipping "example.txt" повинен виводити файл gzipped під назвою "example.txt", а не "example.txt.gz." Чи можливо це зробити елегантно за допомогою однієї команди (не виконуючи наступної mv)?


4
Я трохи цікавий. Чому ти цього хочеш? Це звучить як погана ідея.
Бернхард

3
Так. Ви поміщаєте 2 цілі рядки в сценарій bash і називаєте це "моя-елегантна команда". ;)
золотинки

2
@Bernhard Це частина безперервного процесу інтеграції веб-додатків. Статичні активи (файли CSS, JS) потрібно стискати, не змінюючи ім’я файлу. При доставці до браузера додається заголовок "кодування вмісту: gzip", тому розширення не має значення. Але якщо ім'я файлу буде змінено, я повинен виконати пошук і заміну у вихідних HTML-файлах.
jamieb

Якщо це справді велика проблема для вас, ви можете визначити функцію bash, яка передає $ * виконуваному файлу gzip, а другий рядок робить mv для вас.
Братчлі

4
@ ваша проблема з веб-додатком: будь-який гідний веб-сервер може / зробить стискання для вас ...
Bananguin

Відповіді:


12

Це НЕ працює:

# 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>

Це умова гонки:

# 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

Проблема полягає в тому, що > example.txt(або dd of=example.txtз цього приводу) вбиває файл, перш ніж інший процес матиме можливість його прочитати. Тож очевидного рішення немає, саме тому слід дотримуватися mv.

Існує декілька способів, як можна обдурити. Ви можете відкрити файл, а потім від’єднати його - файл буде існувати до тих пір, поки ви його не закриєте, а потім створити новий файл з тим самим іменем і записати до нього gzipped дані. Однак я не знаю очевидного способу примусити башти використовувати це, і навіть якби я це зробив, моя відповідь все одно буде:

Навіть не роби цього.

Якщо gzipз будь-якої причини виходить з ладу або виникає якась проблема, наприклад, у вас не вистачає місця під час gzipping (оскільки інші процеси записуються, або результат gzip більший, ніж вхідні дані - що відбувається з випадковими даними - тощо), ви просто втратили файл . Вітаємо!

Створіть окремий файл та mvна успіх. Це найпростіший, зрозумілий і найнадійніший метод, який ви коли-небудь знайдете.


1
Як щодо додавання заради повноти:gzip example.txt && mv example.txt.gz example.txt
описувати

2
Жоден декадист не читав ОП - це неелегантно .
goldilocks

@goldilocks "Створіть окремий файл та mvуспішно." можна зробити більш елегантним? Я просто намагався запропонувати відповідь Frostschutz доповнити конкретним прикладом. Якщо mvможна використовувати більш елегантно, ніж я думав, наведіть приклад.
декап

Ваша пропозиція - це простий, елегантний, очевидний підхід, але чи працює він залежить від такої кількості змінних, наприклад, що робити, якщо вже є example.txt.gz? Крім того, не маючи розширень, з якими потрібно працювати, ви повинні якось запобігти gzipping вже gzipped файли. Це зовсім нова банка глистів, але це насправді не було питанням.
frostschutz

10

У мене був такий самий випуск, як частина розгортання CI до AWS S3.

Це те, що я робив для рекурсивного gzipping каталогу (на місці) без .gzсуфікса:

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

Здається, для мене досить чисто. Але так, схоже, вам потрібно mvдесь там.

Якщо ви використовуєте, gruntви можете подивитися grunt-contrib-compress. Деякі gruntінструменти, спеціально розгорнуті до S3, також оброблятимуть gzip.


1
слід find . -type ...НЕ find.додавати простір , будь ласка :)
штучка

2

-S розширення, яке ви хочете

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

призведе до dog.txt_2015_11

при розпакуванні його потрібно вказати розширення.

gzip -d _2015_11 dog.txt_2015_11

У unix використовуйте команду file, щоб визначити, який тип файлу у вас є, розширення вводять в оману або часто відсутні.


1

Я не думаю, що створення файлу gzip без розширення насправді належне робити.

IMHНам слід налаштувати веб-сервер на зчитування файлу .gz. Напевно, у вас вже є таке правило:

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

Вам просто потрібно додати правило, що переписує запитане ім'я файлу, щоб додати ".gz" (насправді, ви повинні перевірити, чи існує файл, як і ви повинні перевірити, чи клієнт перелічив gzip у своєму заголовку Accept-Encoding)


1

Ви можете спробувати веб-сайт s3_we для цього.

Мені не подобається те, що він написаний і в масштабі, і в рубіні, і що йому потрібен JVM. Також мені не подобається припущення, яке він робить (особливо той факт, що він видаляє зайві файли з відра), але він повинен працювати, якщо ви добре з цим.

Я планую самостійно написати такий інструмент, який не має цих обмежень, будьте в курсі.


0

Це насправді не те, що ви повинні робити, головним чином, тому що при передачі цього файлу іншим системам або людям, це може в результаті заплутатися для них і не знайти його як стислий файл.

Якщо ви не хочете використовувати жоден суфікс, GNU не підходить для вас, як gzip -S ""і повернення a gzip: invalid suffix ''.

Однак ви завжди можете надіслати щось на кшталт gzip -S " "(пробіл), і це буде показано так:

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

Згодом, якщо ви хочете розпакувати його, вам доведеться зробити щось на кшталт gunzip -c testfile\ (без зазначення суфіксу) або навіть із -fпрапором.

Я щиро думаю, що додавання mvкоманди до &&не призведе до великих клопотів у вашому коді. У будь-якому випадку, і як сказав @frostschutz, робити це не дуже добре.


Це те, що потрібно, якщо ви хочете використовувати S3 для обслуговування стислих файлів, наприклад, для розміщення статичного веб-сайту. Ви можете врахувати це: github.com/laurilehmijoki/s3_website
Cristian Măgherușan-Stanciu
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.