Estrazione di file .gz contenuti in una cartella


13

Ho una cartella contenente circa 320116 file .pdb.gz. Voglio decomprimerli tutti. Se uso gunzip * .gz mi dà un errore, ovvero un elenco di argomenti troppo lungo. La cartella è di circa 2 GB. Per favore, dammi un suggerimento appropriato.


Se dovrai lavorare su questa struttura di directory a lungo termine, dividi questa directory in molte. Ad esempio in base al tempo di modifica dei file o al nome dei file.
dan

Sì, devo lavorare a lungo termine. sono stati estratti ora voglio suddividerli e classificarli in tre cartelle sulla base dei loro nomi. C'è uno script di shell per farlo?
Lily Sharpton,

Ti consiglio di cercare domande simili lì. Se non ne trovi uno adatto alle tue esigenze, fai la tua nuova domanda.
dan

Risposte:


26
find . -name '*.pdb.gz' -exec gunzip {} +

-exec gunzip {} +fornirà gunzipmolti ma non troppi nomi di file sulla sua riga di comando. Questo è più efficiente di quello -exec gunzip {} \;che avvia un nuovo gunzipprocesso per ogni singolo file.


3
Uno find, meno gunzip!
dan

2
Nota che "+" è un GNUismo e quindi non funzionerà su sistemi non GNU come * BSD.
Ripristina Monica - M. Schröder il

3
Le versioni successive di BSD findconsentono la notazione "+". Vedi, ad esempio, la findpagina man di BSD 10.1 . Vale anche per OS X (almeno 10.9 e successive, forse precedenti).
plasma

7

Ogni volta che si ottengono errori "Elenco argomenti troppo lungo" è possibile aggirare il problema invocando il comando desiderato più volte, ogni volta con un sottoinsieme degli argomenti che si desidera utilizzare. xargsè uno strumento che ti aiuta a farlo automaticamente.

find . -type f -a -name \*.pdb.gz -print0 | xargs -0 gunzip

questo non ha la stessa inefficienza del fatto -execdir gunzip "{}" \;che xargs invocherà gunzip separatamente per ogni file? Questa è la mia lettura della pagina man.
gogoud,

5
No, xargsriempirà tutti i nomi di file che rientrano nella gunzipriga di comando. Provalo! echo a b c d e f | xargs echoinvoca solo echouna volta con tutti e 6 gli argomenti in modo da vedere una riga di output (comando abbastanza inutile da eseguire comunque !!!!) mentre se forzate xargsa fornire solo fino a 3 argomenti per invocazione del comando usando echo a b c d e f | xargs -n 3 echoallora otterrete 2 righe di output .
Celada,

4
Un altro vantaggio dell'utilizzo xargsè che, con l' -Popzione, è possibile eseguire più gunzipprocessi in parallelo, che (a seconda dei parametri esatti del sistema) potrebbe andare più veloce.
psmears,

grazie per il puntatore a -P, @psmears. Ora ho imparato anche qualcosa!
Celada,

1

Penso che dovrebbe funzionare, passa il percorso / nome di ogni file singolarmente a gunzip per l'elaborazione:

find /my/dir -name "*.pdb.gz" -execdir gunzip "{}" \;

1
Ciò eseguirà gunzip una volta per file. Vedi la risposta di John1024 per un modo leggermente diverso che evita quell'inefficienza.
Celada,

@Celada Questo è stato deliberato; la mia preoccupazione era che l'uso di + potesse portare nuovamente a un messaggio di errore a causa del sovraccarico di gunzip. Se il metodo di John1024 funziona, è tecnicamente più efficiente, ma il mio dovrebbe funzionare se non lo fa.
gogoud,

1
findcon +e xargssono espressamente designer con esattamente quel problema in mente. Forniranno sempre quanti più argomenti possibile, pur non superando il limite del sistema operativo. Perché, a proposito, è un limite del sistema operativo, niente a che fare con gunzip.
Celada,

1
@Celada ok grazie per quelle informazioni, quindi presumibilmente con il gunzip '+' potrebbe essere invocato più di una volta, ma meno di 320.000 volte?
gogoud,

1
corretta.
Celada,


1

Se hai una macchina multi-core probabilmente vedrai che l'utilizzo gunzipnon massimizzerà le capacità della tua macchina. Per questo dovresti eseguire più gunzips in parallelo. Tenere traccia di ciò che viene fatto in quale terminale a mano è ingombrante, ma puoi farlo facilmente con GNU parallelo:

find . -name "*.gz" | parallel -X gunzip {}

1
Non fallirà perché l'elenco degli argomenti parallelè troppo lungo?
user253751

@immibis Sì, ho dimenticato il problema originale, aggiornerò il mio post
Anthon il

Non fallirà ancora perché l'elenco degli argomenti findè troppo lungo?
user253751

1
si ma stai passando tutti i nomi di file sulla findriga di comando di.
user253751

Sembra che questo non sia un buon giorno per rispondere alle domande, ho dimenticato di citare l'argomento a-name
Anthon,

-1

Non è necessario usarlo findper questo, poiché non hai menzionato le sottocartelle. Quello che devi fare è:

for f in *.gz;do gunzip $f;done

4
È cosa serve findse non si vuole generare 320116 gunzipprocessi, proprio come questo ciclo fa.
John WH Smith
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.