533 Stimmen

Wie tariere ich ein Verzeichnis mit Dateien und Ordnern, ohne das Verzeichnis selbst einzuschließen?

Das tue ich normalerweise:

tar -czvf my_directory.tar.gz my_directory

Was ist, wenn ich nur alles (einschließlich aller versteckten Systemdateien) in my_directory einschließen möchte, aber nicht das Verzeichnis selbst? Das will ich nicht:

my_directory
   --- my_file
   --- my_file
   --- my_file

Ich möchte:

my_file
my_file
my_file

30voto

mateusza Punkte 4713
cd my_directory
tar zcvf ../my_directory.tar.gz *

20voto

Rob Fisher Punkte 903

Diese Antwort sollte in den meisten Situationen funktionieren. Beachten Sie jedoch, wie die Dateinamen in der tar-Datei gespeichert werden, z. B. als, ./file1 und nicht nur file1 . Ich habe festgestellt, dass dies zu Problemen führt, wenn ich diese Methode verwende, um Tarballs zu manipulieren, die als Paketdateien in BuildRoot .

Eine Lösung besteht darin, einige Bash Globs zu verwenden, um alle Dateien außer .. wie diese:

tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *

Diesen Trick habe ich gelernt von diese Antwort .

Jetzt gibt tar einen Fehler zurück, wenn es keine passenden Dateien gibt ..?* ou .[^.]* aber es wird trotzdem funktionieren. Wenn der Fehler ein Problem ist (Sie prüfen in einem Skript auf Erfolg), funktioniert dies:

shopt -s nullglob
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
shopt -u nullglob

Obwohl wir jetzt mit Shell-Optionen herumspielen, könnten wir zu dem Schluss kommen, dass es sauberer ist, wenn wir * versteckte Dateien abgleichen:

shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob

Dies funktioniert möglicherweise nicht, wenn Ihre Shell Globs * im aktuellen Verzeichnis, also verwenden Sie alternativ:

shopt -s dotglob
cd my_dir
tar -zcvf ../my_dir.tar.gz *
cd ..
shopt -u dotglob

6voto

med Punkte 61
cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..

Diese hier hat bei mir funktioniert und schließt alle versteckten Dateien ein, ohne alle Dateien in ein Root-Verzeichnis mit dem Namen "." zu legen, wie in Antwort von tomoe :

4voto

user2328973 Punkte 41
cd DIRECTORY
tar -czf NAME.tar.gz  *

das Sternchen schließt alles ein, auch versteckte Einträge

4voto

papo Punkte 1269

Befehl

um eine Standard-Archivdatei zu erstellen.

find my_directory/ -maxdepth 1 -printf "%P\n" | tar -cvf my_archive.tar -C my_directory/ -T -

Gepackte Dateien und Verzeichnisse befinden sich im Root des Archivs ohne Pfadangaben und tiefere Dateien haben relative Pfade.
Es gibt keine seltsam aussehenden './' vor Dateien und Verzeichnissen. ('./file')
Es sind keine speziellen Dateien '.' enthalten.

Es scheint, dass ein weiteres Instrument, wie find ou ls ( ls -A -1 ) ist erforderlich, um diese Ziele zu erreichen und tar ist nicht in der Lage, nur mit seinen Argumenten Dateien auszuwählen und ein Archiv mit solchen Anforderungen zu erstellen.

Mit dem obigen Befehl wird eine Archiv-Tar-Datei erstellt, die weiterverarbeitet oder an jemanden weitergegeben werden kann, ohne dass es seltsam aussieht oder eine Erklärung oder ein Werkzeug zum Entpacken benötigt wird.

Argumente Beschreibung

-maxdepth 1
Höchstens 1 Stufe absteigen - kein Rücklauf.
-printf
drucken Format auf der Standardausgabe
%P Name der Datei, wobei der Name des Startpunkts, unter dem sie gefunden wurde, entfernt wird.
\n Zeilenumbruch
printf fügt keinen Zeilenumbruch am Ende der Zeichenkette ein. Er muss hier eingefügt werden

Teer:
-C DIR , --directory=DIR
in das Verzeichnis DIR wechseln

-T FILE , --files-from=FILE
Namen zum Extrahieren oder Erstellen aus DATEI holen
-
die DATEI von oben ist die Standardeingabe aus dem Rohr

Kommentare zu anderen Lösungen.

Das gleiche Ergebnis könnte mit der von @aross beschriebenen Lösung erzielt werden.
Der Unterschied zu dieser Lösung besteht darin, welches Werkzeug die Rekursion durchführt. Wenn Sie die Aufgabe dem find geht jeder Dateipfadname durch die Pipe. Es sendet auch alle Verzeichnisnamen, die tar mit --no-recursion ignoriert oder als leere Namen anfügt, gefolgt von allen Dateien in jedem Verzeichnis. Wenn es unerwartete Ausgaben wie Fehler in Dateien gab, die von find würde tar nicht wissen oder sich nicht darum kümmern, was vor sich geht.
Aber mit weiteren Prüfungen, wie der Verarbeitung des Fehlerstroms von find, könnte es eine gute Lösung sein, wenn viele Optionen und Filter für Dateien erforderlich sind.
Ich ziehe es vor, die Rekursion auf Teer zu belassen, da dies einfacher und damit stabiler zu sein scheint.
Bei meiner komplizierten Verzeichnisstruktur bin ich zuversichtlicher, dass das Archiv vollständig ist, wenn tar keinen Fehler meldet.

Eine weitere Lösung mit find die von @serendrewpity vorgeschlagen wurde, scheint in Ordnung zu sein, aber sie schlägt bei Dateinamen mit Leerzeichen fehl. Der Unterschied ist, dass die Ausgabe von find Die von $() gelieferte Sub-Shell ist durch Leerzeichen unterteilt. Es könnte möglich sein, mit printf Anführungszeichen hinzuzufügen, aber das würde die Anweisung weiter verkomplizieren.

Es gibt keinen Grund, in das Verzeichnis my_directory zu wechseln und dann wieder zurück, wenn man ../my_archive.tar als tar-Pfad verwendet, da TAR über -C DIR , --directory=DIR der genau für diesen Zweck vorgesehen ist.

Verwendung von . (Punkt) wird Punkte enthalten

Mit * kann die Shell die Liste der Eingabedateien liefern. Es könnte möglich sein, Shell-Optionen zu verwenden, um Punktdateien einzuschließen. Aber das ist kompliziert. Der Befehl muss in einer Shell ausgeführt werden, die das erlaubt. Das Aktivieren und Deaktivieren muss vor und nach dem tar-Befehl erfolgen. Und es wird fehlschlagen, wenn das Root-Verzeichnis des zukünftigen Archivs zu viele Dateien enthält.

Der letzte Punkt gilt auch für alle Lösungen, die keine Rohrleitungen verwenden.

Bei den meisten Lösungen wird ein Verzeichnis erstellt, in dem sich die Dateien und Verzeichnisse befinden. Das ist kaum je erwünscht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X