Extraktion von .gz-Dateien in einem Ordner

13

Ich habe einen Ordner mit ca. 320116 .pdb.gz-Dateien. Ich möchte sie alle dekomprimieren. Wenn ich gunzip * .gz verwende, wird mir ein Fehler angezeigt, dh die Argumentliste ist zu lang. Der Ordner ist etwa 2 GB groß. Bitte machen Sie mir einen entsprechenden Vorschlag.

Lily Sharpton
quelle
Wenn Sie langfristig an dieser Verzeichnisstruktur arbeiten müssen, teilen Sie dieses Verzeichnis in mehrere auf. Zum Beispiel basierend auf der Änderungszeit der Dateien oder dem Dateinamen.
Dan
Ja, ich muss langfristig arbeiten. Sie wurden jetzt extrahiert. Ich möchte sie anhand ihrer Namen in drei Ordner unterteilen und klassifizieren. Gibt es ein Shell-Skript, um dies zu tun?
Lily Sharpton
Ich empfehle Ihnen, dort nach ähnlichen Fragen zu suchen. Wenn Sie keine finden, die Ihren Anforderungen entspricht, stellen Sie Ihre eigene neue Frage.
Dan

Antworten:

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

-exec gunzip {} +wird gunzipmit vielen, aber nicht zu vielen Dateinamen in der Kommandozeile versehen. Dies ist effizienter als -exec gunzip {} \;das Starten eines neuen gunzipProzesses für jede einzelne Datei.

John1024
quelle
3
Eins findweniger gunzip!
Dan
2
Beachten Sie, dass das "+" ein GNUism ist und daher nicht auf Nicht-GNU-Systemen wie * BSD funktioniert.
Wiedereinsetzung von Monica - M. Schröder am
3
Spätere BSD-Versionen finderlauben die "+" - Notation. Siehe zum Beispiel die findManpage für BSD 10.1 . Gilt auch für OS X (mindestens 10.9 und später, möglicherweise früher).
Plasma
7

Immer wenn Sie die Fehlermeldung "Argumentliste zu lang" erhalten, können Sie sie umgehen, indem Sie den gewünschten Befehl mehrmals aufrufen, jeweils mit einer Teilmenge der Argumente, die Sie verwenden möchten. xargsist ein Tool, mit dem Sie dies automatisch tun können.

find . -type f -a -name \*.pdb.gz -print0 | xargs -0 gunzip
Celada
quelle
hat dies nicht die gleiche ineffizienz wie -execdir gunzip "{}" \;xargs, das gunzip für jede datei separat aufruft? Das ist meine Lektüre der Manpage.
Gogoud
5
Nein, es xargswerden so viele Dateinamen gespeichert, wie in die gunzipBefehlszeile passen . Versuch es! echo a b c d e f | xargs echoRuft nur echoeinmal mit allen 6 Argumenten auf, sodass Sie eine Ausgabezeile sehen (ziemlich unnützer Befehl, der ausgeführt werden muss !!!!). Wenn Sie jedoch erzwingen xargs, nur bis zu 3 Argumente pro Aufruf des Befehls mit echo a b c d e f | xargs -n 3 echoanzugeben, erhalten Sie 2 Ausgabezeilen .
Celada
4
Ein weiterer Vorteil der Verwendung xargsist, dass Sie mit dieser -POption mehrere gunzipProzesse parallel ausführen können, was (abhängig von den genauen Parametern Ihres Systems) möglicherweise schneller geht.
Psmears
danke für den -Phinweis auf , @psmears. Jetzt habe ich auch was gelernt!
Celada,
1

Ich denke das sollte funktionieren, es übergibt den Pfad / Namen jeder Datei einzeln an gunzip zur Verarbeitung:

find /my/dir -name "*.pdb.gz" -execdir gunzip "{}" \;
Gogoud
quelle
1
Dadurch wird gunzip einmal pro Datei ausgeführt. Siehe John1024 Antwort für eine etwas andere Art und Weise, dass die Ineffizienz vermeidet.
Celada
@ Celada Dies war absichtlich; Ich befürchtete, dass die Verwendung von + aufgrund der Überlastung von gunzip erneut zu einer Fehlermeldung führen könnte. Wenn die Methode von John1024 funktioniert, ist sie technisch effizienter, aber meine sollte funktionieren, wenn seine nicht funktioniert.
Gogoud
1
findmit +und xargssind ausdrücklich Designer mit genau diesem Thema im Auge. Sie liefern immer so viele Argumente wie möglich, wobei das Limit des Betriebssystems nicht überschritten wird. Weil es sich übrigens um eine Betriebssystembeschränkung handelt, die nichts damit zu tun hat gunzip.
Celada
1
@Celada ok danke für diese Info, also wird vermutlich mit '+' gunzip mehrmals aufgerufen, aber weniger als 320.000 mal?
Gogoud
1
richtig.
Celada
1

Versuchen Sie diesen Weg:

find . -name '*.gz' -exec gunzip {} \;
jherran
quelle
3
Das wird gunzipeinmal pro Datei ausgeführt. Siehe John1024 Antwort für eine etwas andere Art und Weise, dass die Ineffizienz vermeidet.
Celada
Stellen
1

Wenn Sie einen Multi-Core-Rechner haben, werden Sie wahrscheinlich feststellen, dass gunzipdie Leistungsfähigkeit Ihres Rechners durch die Verwendung nicht voll ausgeschöpft wird. Dafür müssten Sie mehrere gunzips parallel ausführen . Zu verfolgen, was in welchem ​​Terminal von Hand gemacht wird, ist umständlich, aber das können Sie mit GNU parallel leicht tun:

find . -name "*.gz" | parallel -X gunzip {}
Anthon
quelle
1
Wird das nicht scheitern, weil die Argumentliste parallelzu lang ist?
user253751
@immibis Ja, ich habe das ursprüngliche Problem vergessen, ich aktualisiere meinen Beitrag
Anthon
Schlägt das nicht immer noch fehl, weil die Argumentliste findzu lang ist?
user253751
1
Ja, aber Sie übergeben alle Dateinamen in findder Befehlszeile.
user253751
Scheint, dies ist kein guter Tag, um Fragen zu beantworten, ich habe vergessen, das Argument zu zitieren-name
Anthon
-1

Es ist nicht notwendig, finddies zu verwenden, da Sie Unterordner nicht erwähnt haben. Was Sie tun müssen, ist:

for f in *.gz;do gunzip $f;done
Tolga Ozses
quelle
4
Sie tun müssen , findwenn Sie nicht möchten , 320.116 laichen gunzipProzesse, wie diese Schleife tut.
John WH Smith