¿Cómo crear un archivo gzip sin la extensión de archivo .gz?

14

Me gustaría crear un archivo comprimido que conserve el nombre del archivo original. Por ejemplo, gzipping "example.txt" debería generar un archivo comprimido denominado "example.txt" en lugar de "example.txt.gz". ¿Es posible hacer esto elegantemente con un comando (sin hacer un posterior mv)?

jamieb
fuente
44
Tengo un poco de curiosidad ¿Por qué quieres esto? Suena como una mala idea.
Bernhard
3
Si. Pones 2 líneas enteras en un script bash y lo llamas "mi-elegante-comando". ;)
Ricitos de Oro
2
@Bernhard Es parte de un proceso de construcción de integración continua para una aplicación web. Los activos estáticos (CSS, archivos JS) deben comprimirse sin cambiar el nombre del archivo. Cuando se entrega al navegador, se incluye un encabezado "codificación de contenido: gzip", por lo que la extensión es irrelevante. Pero si se cambia el nombre de archivo, tengo que hacer una búsqueda y reemplazo en los archivos HTML de origen.
jamieb
Si esto es realmente un gran problema para usted, podría definir una función bash que pase $ * al ejecutable gzip y la segunda línea haga el mv por usted.
Bratchley
44
@su problema de aplicación web: cualquier servidor web decente puede / hará la compresión por usted ...
Bananguin

Respuestas:

12

Esto no funciona:

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

Esta es una condición de carrera:

# 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

El problema es que el > example.txt(o dd of=example.txtpara el caso) mata el archivo antes de que el otro proceso tenga la oportunidad de leerlo. Por lo tanto, no hay una solución obvia, razón por la cual debe seguir mv.

Hay varias formas de hacer trampa. Puede abrir el archivo, luego desvincularlo (el archivo continuará existiendo hasta que lo cierre) y luego crear un nuevo archivo con el mismo nombre y escribir los datos comprimidos en él. Sin embargo, no conozco una forma obvia de obligar a bash a usar eso, e incluso si lo supiera, mi respuesta sería:

Ni siquiera lo hagas.

Si gzipfalla por algún motivo, o se produce algún problema, como que se está quedando sin espacio mientras se comprime (porque otros procesos están escribiendo, o el resultado de gzip es mayor que la entrada, que ocurre con datos aleatorios, etc.), acaba de perder su archivo . ¡Felicidades!

Cree un archivo separado y mven caso de éxito. Ese es el método más simple, fácil de entender y más confiable que jamás encontrará.

Frostschutz
fuente
1
¿Qué tal agregar por el bien de la integridad:gzip example.txt && mv example.txt.gz example.txt
depquid
2
No lea con descuido el OP, eso no es elegante .
Ricitos de Oro
@goldilocks "Cree un archivo separado y mven caso de éxito". se puede hacer más elegante? Solo intentaba proponer que la respuesta de frostschutz se aumentara con un ejemplo específico. Si mvpuede usarse con más elegancia de lo que pensaba, por favor, dé un ejemplo.
depquid
Su sugerencia es el enfoque simple, elegante y obvio, pero si funciona depende de tantas variables, por ejemplo, ¿qué hacer si ya hay un ejemplo.txt.gz? Además, sin ninguna extensión con la que trabajar, debe evitar de alguna manera comprimir archivos ya comprimidos. Esa es una nueva lata de gusanos, pero esa no era realmente parte de la pregunta.
frostschutz
10

Tuve el mismo problema, como parte de una implementación de CI en AWS S3.

Esto es lo que hice para comprimir recursivamente un directorio (en su lugar) sin el .gzsufijo:

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

Parece lo suficientemente limpio para mí. Pero sí, parece que necesitas una mven algún lado.

Si estás usando gruntpuedes mirar grunt-contrib-compress. Algunas de las gruntherramientas específicas para implementar en S3 también manejarán gzip para usted.

Tobek
fuente
1
find . -type ...no se debe find.agregar el espacio por favor :)
Humdinger
2

-S extensión que desea

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

dará como resultado dog.txt_2015_11

cuando lo descomprimes debes especificar la extensión.

gzip -d _2015_11 dog.txt_2015_11

En Unix, use el comando de archivo para determinar qué tipo de archivo tiene, las extensiones son engañosas o faltan a menudo.

usuario143758
fuente
1

No creo que crear un archivo gzip sin extensión sea realmente lo correcto.

IMHo debe configurar su servidor web para leer el archivo .gz. Probablemente ya tengas una regla como esta:

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

Solo necesita agregar una regla que reescriba el nombre de archivo solicitado para agregar ".gz" (en realidad, debe verificar que el archivo exista, al igual que debe verificar que el cliente enumeró gzip en su encabezado Accept-Encoding)

Ángel
fuente
1

Puede probar s3_website para esto.

No me gusta el hecho de que está escrito en escala y rubí y que necesita una JVM. Además, no me gusta la suposición que hace (especialmente el hecho de que elimina archivos adicionales del cubo), pero debería funcionar si estás de acuerdo con eso.

Estoy planeando escribir una herramienta como esta que no tenga estas limitaciones, estad atentos.

Cristian Măgherușan-Stanciu
fuente
0

Esto no es realmente algo que debería estar haciendo, principalmente porque al transferir este archivo a otros sistemas o personas, podría terminar siendo confuso para ellos y no encontrarlo como un archivo comprimido.

Si no desea utilizar ningún sufijo, entonces GNU no es bueno para usted, como gzip -S ""devolvería a gzip: invalid suffix ''.

Sin embargo, siempre puede enviar algo como gzip -S " "(espacio en blanco), y se mostrará así:

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

Luego, si desea descomprimirlo, tendrá que hacer algo como gunzip -c testfile\ (sin especificar el sufijo), o incluso con la -fbandera.

Sinceramente, creo que agregar un mvcomando con &&no supondría una molestia para su código. De todos modos, y como ha dicho @frostschutz, no es una muy buena idea hacer esto.

AleksanderKseniya
fuente
Esto es algo que se necesita si desea utilizar S3 para servir archivos comprimidos, como para alojar un sitio web estático. Puede considerar esto: github.com/laurilehmijoki/s3_website
Cristian Măgherușan-Stanciu