Jak utworzyć plik gzip bez rozszerzenia .gz?

14

Chciałbym utworzyć plik spakowany gzip, który zachowuje oryginalną nazwę pliku. Na przykład gzipping „example.txt” powinien wypisać plik gzipowany o nazwie „example.txt” zamiast „example.txt.gz”. Czy można to zrobić elegancko za pomocą jednego polecenia (nie wykonując kolejnego mv)?

jamieb
źródło
4
Jestem trochę ciekawy. Dlaczego tego chcesz Brzmi jak zły pomysł.
Bernhard
3
Tak. Umieszczasz 2 całe linie w skrypcie bash i nazywasz to „my-elegant-command”. ;)
goldilocks
2
@Bernhard Jest to część procesu ciągłej integracji aplikacji internetowej. Zasoby statyczne (pliki CSS, JS) muszą zostać skompresowane bez zmiany nazwy pliku. Dostarczony do przeglądarki zawiera nagłówek „kodowanie zawartości: gzip”, więc rozszerzenie nie ma znaczenia. Ale jeśli nazwa pliku zostanie zmieniona, muszę przeprowadzić wyszukiwanie i zamianę w źródłowych plikach HTML.
jamieb
Jeśli tak naprawdę jest to dla ciebie problem, możesz zdefiniować funkcję bash, która przekazuje $ * do pliku wykonywalnego gzip, a druga linia wykonuje dla ciebie mv.
Bratchley,
4
@ twój problem z aplikacją internetową: każdy porządny serwer może / zrobi dla ciebie kompresję ...
Bananguin 21.03.2013

Odpowiedzi:

12

To nie działa:

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

To jest warunek wyścigu:

# 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

Problem polega na tym, że > example.txt(lub dd of=example.txtw tym przypadku) zabija plik, zanim inny proces będzie miał szansę go odczytać. Więc nie ma oczywistego rozwiązania, dlatego powinieneś się trzymać mv.

Istnieje wiele sposobów oszukiwania. Możesz otworzyć plik, a następnie odłączyć go - plik będzie istniał do momentu jego zamknięcia - a następnie utwórz nowy plik o tej samej nazwie i zapisz do niego skompresowane dane. Jednak nie znam oczywistego sposobu na zmuszenie basha do użycia tego, a nawet gdybym to zrobił, moja odpowiedź byłaby nadal:

Nawet tego nie rób.

Jeśli gzipz jakiegoś powodu zawiedzie lub wystąpi jakiś problem, na przykład gdy zabraknie Ci miejsca podczas gzipowania (ponieważ inne procesy zapisują lub wynik gzip jest większy niż dane wejściowe - co dzieje się w przypadku losowych danych - itp.), Właśnie straciłeś plik . Gratulacje!

Utwórz osobny plik i mvna sukces. To najprostsza, łatwa do zrozumienia i najbardziej niezawodna metoda, jaką kiedykolwiek znajdziesz.

frostschutz
źródło
1
Co powiesz na dodanie w celu uzupełnienia:gzip example.txt && mv example.txt.gz example.txt
depquid
2
Brak depquid czyta OP - to nieeleganckie .
goldilocks
@goldilocks „Utwórz osobny plik i mvna sukces”. może być bardziej elegancki? Chciałem tylko zaproponować, aby odpowiedź frostschutza została wzbogacona o konkretny przykład. Jeśli mvmożna go używać bardziej elegancko, niż myślałem, proszę podać przykład.
depquid
Twoja sugestia to proste, eleganckie i oczywiste podejście, ale to, czy zadziała, zależy od tylu zmiennych, np. Co robisz, jeśli już istnieje przykład.txt.gz? Również bez rozszerzenia do pracy, musisz jakoś zapobiec gzipowaniu już spakowanych plików. To całkiem nowa puszka robaków, ale tak naprawdę nie było tego pytania.
frostschutz
10

Miałem ten sam problem w ramach wdrożenia CI w AWS S3.

Oto co zrobiłem dla rekursywnego gzipowania katalogu (na miejscu) bez .gzprzyrostka:

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

Wydaje mi się wystarczająco czysty. Ale tak, wygląda na to, że potrzebujesz mvgdzieś tam.

Jeśli używasz, gruntmożesz na to spojrzeć grunt-contrib-compress. Niektóre z gruntnarzędzi specjalnie do wdrażania na S3 obsłużą również gzip.

Tobek
źródło
1
powinien być find . -type ...nie find.dodać przestrzeń proszę :)
Humdinger
2

-S rozszerzenie, które chcesz

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

spowoduje dog.txt_2015_11

po rozpakowaniu musisz podać rozszerzenie.

gzip -d _2015_11 dog.txt_2015_11

W Uniksie użyj polecenia file, aby określić, jaki typ pliku posiadasz, rozszerzenia wprowadzają w błąd lub często ich brakuje.

użytkownik143758
źródło
1

Nie sądzę, aby tworzenie pliku gzip bez rozszerzenia było naprawdę właściwe.

IMHo, powinieneś skonfigurować swój serwer WWW do odczytu pliku .gz. Prawdopodobnie masz już taką zasadę:

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

Wystarczy dodać regułę przepisującą żądaną nazwę pliku, aby dodać „.gz” (tak naprawdę powinieneś sprawdzić, czy plik istnieje, tak samo jak powinieneś sprawdzić, czy klient umieścił gzip w nagłówku Accept-Encoding)

Anioł
źródło
1

Możesz spróbować s3_website do tego.

Nie podoba mi się fakt, że jest napisany zarówno w języku scala, jak i rubinowym i że potrzebuje JVM. Nie podoba mi się też to założenie (szczególnie fakt, że usuwa dodatkowe pliki z wiadra), ale powinno działać, jeśli nie masz nic przeciwko.

Planuję napisać takie narzędzie, które nie ma tych ograniczeń, bądźcie czujni.

Cristian Măgherușan-Stanciu
źródło
0

To nie jest tak naprawdę powinieneś robić, głównie dlatego, że podczas przesyłania tego pliku do innych systemów lub osób może to być dla nich mylące i nie znaleźć go jako skompresowanego pliku.

Jeśli nie chcesz używać żadnego sufiksu, GNU nie jest dla ciebie dobre, tak jak gzip -S ""zwróciłoby a gzip: invalid suffix ''.

Zawsze możesz jednak wysłać coś w rodzaju gzip -S " "(spacja), a zostanie to pokazane w następujący sposób:

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

Następnie, jeśli chcesz go zdekompresować, będziesz musiał zrobić coś takiego gunzip -c testfile\ (bez określania sufiksu), a nawet z -fflagą.

Szczerze myślę, że dodanie mvpolecenia z &&nie spowodowałoby tak dużego problemu w twoim kodzie. W każdym razie, jak powiedział @frostschutz, zrobienie tego nie jest dobrym pomysłem.

Aleksander Ksenia
źródło
Jest to coś, co jest potrzebne, jeśli chcesz używać S3 do udostępniania skompresowanych plików, na przykład do hostowania statycznej strony internetowej. Można to rozważyć: github.com/laurilehmijoki/s3_website
Cristian Măgherușan-Stanciu