¿Hay alguna manera de forzar a gzip a no sobrescribir archivos en conflicto?

17

Estoy escribiendo un script en el que estoy comprimiendo archivos.

Existe la posibilidad de que pueda comprimir un archivo, crear un archivo con el mismo nombre e intentar comprimir esto también, p. Ej.

$ ls -l archive/
total 4
-rw-r--r-- 1 xyzzy xyzzy  0 Apr 16 11:29 foo
-rw-r--r-- 1 xyzzy xyzzy 24 Apr 16 11:29 foo.gz

$ gzip archive/foo
gzip: archive/foo.gz already exists; do you wish to overwrite (y or n)? n   
    not overwritten

Al usar gzip --force, puedo forzar a gzip a sobrescribir foo.gz, pero en este caso, creo que hay una buena posibilidad de que pueda perder datos si sobrescribo foo.gz. No parece haber un cambio de línea de comando para forzar a gzip a dejar los .gzarchivos solos ... una versión no interactiva de presionar 'n' en el indicador.

Lo intenté gzip --noforcey gzip --no-force, con la esperanza de que estos pudieran seguir el estándar de opciones de GNU, pero ninguno de estos funcionó.

¿Existe una solución directa para esto?

Editar:

Resulta que esta es una de las veces que vale la pena leer la página de información en lugar de la página de manual.

Desde la página de información:

`--force'
`-f'
     Force compression or decompression even if the file has multiple
     links or the corresponding file already exists, or if the
     compressed data is read from or written to a terminal.  If the
     input data is not in a format recognized by `gzip', and if the
     option `--stdout' is also given, copy the input data without
     change to the standard output: let `zcat' behave as `cat'.  If
     `-f' is not given, and when not running in the background, `gzip'
     prompts to verify whether an existing file should be overwritten.

En la página del manual faltaba el texto y cuando no se ejecutaba en segundo plano.

Cuando se ejecuta en segundo plano, gzip no aparecerá y no se sobrescribirá a menos que -fse invoque la opción.

Barton Chittenden
fuente
3
No estoy seguro de cómo gzip comprueba si tiene antecedentes, pero agregar '&' en bash en el sistema en el que estoy trabajando no lo hace. Sin embargo, estar del otro lado de una tubería parece funcionar, así que en lugar de: find ./ ! -name "*gz" -exec gzip {} \; & esto funciona: find ./ ! -name "*gz" -print0 | xargs -0 -n 1 -t gzip informes de gzip: gzip: ./2012-July.txt.gz already exists; not overwritten
Bill McGonigle
1
@BillMcGonigle ¡Tu comentario debería ser LA respuesta!
Rockallite

Respuestas:

9

Me di cuenta de que la mejor manera de evitar el efecto no deseado es no pedirle al programa que realice el efecto no deseado. Es decir, simplemente no le diga que comprima un archivo si el archivo ya está presente en forma comprimida.

p.ej:

if [ ! -f "$file.gz" ]; then 
    gzip "$file"; 
else 
    echo "skipping $file"
fi

o más corto (ejecutar truesi hay un archivo.gz, comprimir el archivo de lo contrario)

[ -f "$file.gz" ] && echo "skipping $file" || gzip "$file"    
Ярослав Рахматуллин
fuente
Desafortunadamente, esto se está ejecutando como un comando del sistema dentro de un script perl (larga historia sobre por qué no estamos usando algo como IO :: Compress :: Gzip, confía en mí, lo he pensado). El comando de compresión en sí se almacena en un archivo de configuración. Su último comando se parece mucho a lo que necesito, pero creo que he encontrado algo que satisfará mis necesidades un poco mejor. Voy a aceptar su respuesta, porque es una solución general mejor que la mía, pero vea a continuación lo que realmente voy a usar.
Barton Chittenden
Puedes meter un archivo en Perl ...
Ррослав Рахматуллин
1
No estoy claro a qué te refieres poke a file.
Barton Chittenden
La falta de asociación / uso de imágenes en las comunicaciones cotidianas en inglés americano me sorprende cada vez :) Permítanme intentar explicarlo. Evoca una imagen de un niño empujando un cuervo muerto con un palo para ver si está vivo o no. Poking se utiliza para buscar atributos aquí. Del mismo modo, pinchar un archivo significaría verificar algo al respecto, como si está presente. En cualquier caso, creo que el acto de hurgar debería, como mínimo, significa "alcanzar el contacto con un objeto exterior" , y eso es suficiente para decir "obtener información sobre un archivo" con una imagen, en lugar de explicarlo.
Ярослав Рахматуллин
"poke" es a menudo una jerga de hackers para configurar una ubicación de memoria. Ver: en.wikipedia.org/wiki/PEEK_and_POKE#Generic_usage_of_.22POKE.22
Bill McGonigle
12

Lo más cercano que podría encontrar a un solo comando es lo siguiente:

yes n | gzip archive/foo

El yescomando imprime yseguido de un salto de línea a stdout hasta que recibe una señal. Si tiene un argumento, lo imprimirá en lugar de y. En este caso, se imprime nhasta que gzip sale, cerrando así la tubería.

Esto es equivalente a ingresar nrepetidamente en el teclado; esto responderá automáticamente la preguntagzip: archive/foo.gz already exists; do you wish to overwrite (y or n)?

En general, creo que es mejor no intentar comprimir los archivos si existe el archivo comprimido correspondiente; mi solución es más ruidosa, pero se ajusta a mis necesidades particulares de un reemplazo directo para el gzipcomando, ubicado en un archivo de configuración.

Barton Chittenden
fuente
1
otra molestia con esto es que gzipsale2
Steven Penny