wake-up-neo.com

Wie können Sie mehrere Dateien gleichzeitig entpacken?

Ich habe eine Reihe von tar Dateien in einem Verzeichnis und möchte alle Dateien auf einmal daraus extrahieren. Dies scheint aber nichts zu bewirken:

$ tar xf *.tar

Was ist denn hier los? Wie entpacke ich mehrere Dateien gleichzeitig?

65
Jon Ericson

Was ist denn hier los?

Ursprünglich war der Befehl tar für die Verwendung mit Magnetbandgeräten vorgesehen. Da es nur sinnvoll war, tar auf einem Gerät gleichzeitig auszuführen, wurde die Syntax so konzipiert, dass nur ein Gerät verwendet wird. Es wurde angenommen, dass die erste übergebene Datei oder das erste übergebene Verzeichnis das Gerät ist, auf dem sich das betreffende Archiv befindet, sowie alle anderen Dateien oder Verzeichnisse, in denen der Inhalt des Archivs in die Operation einbezogen werden soll. Für die tar -Extraktion (die x -Option) wäre die zuerst übergebene Datei das Archiv und alle anderen Dateien wären die zu extrahierenden Dateien. Wenn es also zwei *.tar - Dateien gibt (sagen Sie a.tar Und b.tar), Würde Ihr Befehl folgendermaßen erweitert:

$ tar xf a.tar b.tar

Sofern a.tar Keine Datei mit dem Namen b.tar Enthält, hat der Befehl tar nichts zu tun und wird im Hintergrund beendet. Ärgerlicherweise meldet die Solaris-Version von tar keine Probleme, weder im Rückkehrcode noch mit der ausführlichen Option (v). In der Zwischenzeit gibt GNU tar2 Und Spam STDERR zurück, auch wenn die ausführliche Option deaktiviert ist:

tar: b.tar: Not found in archive
tar: Exiting with failure status due to previous errors

Wie entpacke ich mehrere Dateien gleichzeitig?

Es ist zu spät, tar neu zu schreiben, um mehrere Archivdateien als Eingabe zu akzeptieren, aber es ist nicht zu schwierig, die Einschränkung zu umgehen.

Für die meisten Benutzer ist es am sinnvollsten, tar für mehrere Archive mehrfach auszuführen. Wenn Sie nur einen Dateinamen an tar xf Übergeben, werden alle archivierten Dateien wie erwartet extrahiert. Ein Ansatz ist die Verwendung einer Shell for -Schleife:

$ for f in *.tar; do tar xf "$f"; done

Eine andere Methode ist die Verwendung von xargs:

$ ls *.tar | xargs -i tar xf {}

Alternativ können Sie einen von mehreren alternative tar Dateireader verwenden. Schließlich könnte der wirklich engagierte Programmierer leicht eine tar -Ersetzung schreiben, die genau wie gewünscht funktioniert. Das Format ist unkompliziert und in vielen Programmiersprachen stehen Bibliotheken zum Lesen von tar -Dateien zur Verfügung. Wenn Sie beispielsweise Perl-Programmierer sind, schauen Sie sich das Modul Archive::Tar an.

Eine Warnung

Das blinde Entpacken mehrerer Dateien kann zu unerwarteten Problemen führen. Am offensichtlichsten ist, dass ein bestimmter Dateiname in mehreren tar -Dateien enthalten sein kann. Da tar standardmäßig Dateien überschreibt, hängt die genaue Version der Datei, die Sie erhalten, von der Reihenfolge ab, in der die Archive verarbeitet werden. Noch beunruhigender ist, dass Sie möglicherweise eine beschädigte Kopie der Datei erhalten, wenn Sie diese "clevere" Optimierung ausprobieren:

for f in *.tar; do
  tar xf "$f" &
done
wait

Wenn sowohl a.tar Als auch b.tar Dieselbe Datei enthalten und gleichzeitig versuchen, sie zu extrahieren, sind die Ergebnisse unvorhersehbar.

Ein verwandtes Problem, insbesondere wenn Archive aus nicht vertrauenswürdigen Quellen entnommen werden, ist die Möglichkeit einer Tarbomb .

Eine Teillösung wäre, automatisch ein neues Verzeichnis zu erstellen, in das extrahiert werden soll:

for f in *.tar; do 
  d=`basename "$f" .tar`
  mkdir "$d"
  (cd "$d" && tar xf "../$f")
done

Dies hilft nicht, wenn eine Datei im Archiv mit einem absoluten Pfad angegeben wird (was normalerweise ein Zeichen für böswillige Absicht ist). Das Hinzufügen dieser Art von Scheck bleibt dem Leser als Übung.

129
Jon Ericson

Wenn sich alle tar-Dateien im selben Ordner befinden, mache ich das in der tcsh-Shell. Funktioniert die ganze Zeit.

find -iname \*.tar -exec tar -xvf {} \;

Dies ist das Gleiche wie die obige Antwort, ein bisschen prägnanter denke ich.

11
Snehashis Roy
find . -maxdepth 1 -name '*.tar' -exec tar -xf '{}' \;
5
user3734617