C'è un modo per forzare gzip a non sovrascrivere i file in conflitto?


17

Sto scrivendo uno script in cui sto comprimendo i file.

C'è la possibilità che io possa comprimere un file, creare un file con lo stesso nome e provare anche a decomprimerlo, ad es.

$ 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

Usando gzip --force, posso forzare gzip a sovrascrivere foo.gz, ma in questo caso, penso che ci siano buone probabilità che potrei perdere dati se sovrascrivo foo.gz. Non sembra esserci un interruttore da riga di comando per forzare gzip a lasciare i .gzfile da solo ... una versione non interattiva di premere 'n' al prompt.

Ho provato gzip --noforcee gzip --no-force, sperando che questi potessero seguire lo standard delle opzioni GNU, ma nessuno dei due ha funzionato.

C'è una soluzione semplice per questo?

Modificare:

Si scopre che questa è una delle volte che paga leggere la pagina di informazioni piuttosto che la pagina di manuale.

Dalla pagina delle informazioni:

`--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.

Nella pagina man mancava il testo e quando non era in esecuzione in background

Quando viene eseguito in background, gzip non verrà richiesto e non verrà sovrascritto a meno che non venga -finvocata l' opzione.


3
Non sono sicuro di come gzip verifichi di essere in background, ma l'aggiunta di '&' in bash sul sistema su cui sto lavorando non lo fa. Essere dall'altra parte di un tubo sembra funzionare, quindi, invece di: find ./ ! -name "*gz" -exec gzip {} \; & questo funziona: find ./ ! -name "*gz" -print0 | xargs -0 -n 1 -t gzip gzip riporta: gzip: ./2012-July.txt.gz already exists; not overwritten
Bill McGonigle,

1
@BillMcGonigle Il tuo commento dovrebbe essere LA risposta!
Rockallite,

Risposte:


9

Mi sono reso conto che il modo migliore per evitare l'effetto indesiderato è di non chiedere al programma di eseguire l'effetto indesiderato. Cioè, semplicemente non dirgli di comprimere un file se il file è già presente in forma compressa.

per esempio:

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

o più breve (esegui truese c'è un file.gz, comprimi il file altrimenti)

[ -f "$file.gz" ] && echo "skipping $file" || gzip "$file"    

Sfortunatamente, questo viene eseguito come comando di sistema all'interno di uno script perl (lunga storia sul perché non stiamo usando qualcosa come IO :: Compress :: Gzip, fidati di me, ci ho pensato). Il comando di compressione stesso è memorizzato in un file di configurazione. Il tuo ultimo comando sembra vicino a quello di cui ho bisogno, ma penso di aver trovato qualcosa che si adatta alle mie esigenze solo un po 'meglio. Accetterò la tua risposta, perché è una soluzione generale migliore della mia, ma vedi sotto per quello che sto per usare.
Barton Chittenden,

Puoi creare un file in Perl ...
рослав Рахматуллин

1
Non sono chiaro cosa intendi per poke a file.
Barton Chittenden,

La mancanza di associazione / utilizzo delle immagini nelle comunicazioni quotidiane in inglese americano mi sorprende ogni volta :) Lasciami provare a spiegare. Evoca l'immagine di un bambino che colpisce un corvo morto con un bastone per vedere se è vivo o no. Il poking è usato per sondare gli attributi qui. Allo stesso modo, cercare un file significherebbe controllarne qualcosa, come se fosse del tutto presente. Ad ogni modo, penso che l'atto di colpire dovrebbe almeno significare "raggiungere un contatto con un oggetto esterno" , e questo è abbastanza per dire "ottenere alcune informazioni su un file" con un'immagine, invece di spiegarlo.
Ярослав Рахматуллин

"poke" è spesso gergo di hacker per l'impostazione di una posizione di memoria. Vedi: en.wikipedia.org/wiki/PEEK_and_POKE#Generic_usage_of_.22POKE.22
Bill McGonigle

12

La cosa più vicina che ho trovato a un singolo comando è la seguente:

yes n | gzip archive/foo

Il yescomando stampa yseguito da un avanzamento riga per stdout fino a quando non riceve un segnale. Se ha un argomento, lo stamperà invece di y. In questo caso, stampa nfino all'uscita di gzip, chiudendo così il tubo.

Questo è l'equivalente di entrare nripetutamente sulla tastiera; questo risponderà automaticamente alla domandagzip: archive/foo.gz already exists; do you wish to overwrite (y or n)?

In generale, penso che sia meglio non provare a comprimere i file se esiste il file gzipped corrispondente; la mia soluzione è più rumorosa, ma si adatta alle mie particolari esigenze di sostituzione drop-in per il gzipcomando, che si trova in un file di configurazione.


1
un altro fastidio è che gzipesce2
Steven Penny,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.