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

833voto

dubek Punkte 10669

Verwenden Sie die -C Wechsel von Teer:

tar -czvf my_directory.tar.gz -C my_directory .

El -C my_directory sagt tar, dass es das aktuelle Verzeichnis in my_directory und dann . bedeutet "das gesamte aktuelle Verzeichnis hinzufügen" (einschließlich versteckter Dateien und Unterverzeichnisse).

Stellen Sie sicher, dass Sie -C my_directory bevor Sie es tun . sonst erhalten Sie die Dateien im aktuellen Verzeichnis.

271voto

tomoe Punkte 2938
cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd - 

sollte die Aufgabe in einer Zeile erledigen. Es funktioniert auch gut für versteckte Dateien. "*" expandiert versteckte Dateien nicht durch Pfadnamen-Expansion, zumindest in der Bash. Unten ist mein Experiment:

$ mkdir my_directory
$ touch my_directory/file1
$ touch my_directory/file2
$ touch my_directory/.hiddenfile1
$ touch my_directory/.hiddenfile2
$ cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd ..
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
$ tar ztf my_dir.tgz
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2

82voto

mateusza Punkte 4713

Sie können auch wie gewohnt ein Archiv erstellen und es mit entpacken:

tar --strip-components 1 -xvf my_directory.tar.gz

64voto

aross Punkte 2823

TL;DR (keine ./ und keine ./file1 !)

find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

Unter bestimmten Bedingungen (nur Dateien, Verzeichnisse und Symlinks archivieren):

find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

Erläuterung

Das folgende Verzeichnis enthält leider ein übergeordnetes Verzeichnis ./ im Archiv:

tar -czf mydir.tgz -C /my/dir .

Sie können alle Dateien aus diesem Verzeichnis verschieben, indem Sie den Befehl --transform Konfigurationsoption, aber das beseitigt nicht die . Verzeichnis selbst. Es wird immer schwieriger, den Befehl zu zähmen.

Sie könnten verwenden $(find ...) um dem Befehl eine Dateiliste hinzuzufügen (wie in Magnus' Antwort ), aber das führt möglicherweise zu einem "Dateiliste zu lang"-Fehler. Der beste Weg ist die Kombination mit tar's -T Option, etwa so:

find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

Im Wesentlichen werden alle Dateien aufgelistet ( -type f ), Links ( -type l ) und Unterverzeichnisse ( -type d ) unter Ihrem Verzeichnis, machen Sie alle Dateinamen relativ mit -printf "%P\n" und dann an den tar-Befehl übergeben (er nimmt die Dateinamen von STDIN mit -T - ). Die Website -C ist erforderlich, damit tar weiß, wo sich die Dateien mit relativen Namen befinden. Die Option --no-recursion Flag ist, damit tar nicht in Verzeichnisse rekursiert, die es archivieren soll (was zu doppelten Dateien führt).

Wenn Sie etwas Spezielles mit Dateinamen machen müssen (Filtern, Verfolgen von Symlinks usw.), kann der find Befehl ist ziemlich mächtig, und Sie können ihn testen, indem Sie einfach die tar Teil des obigen Befehls:

$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore

Wenn Sie zum Beispiel PDF-Dateien filtern wollen, fügen Sie ! -name '*.pdf'

$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore

Nicht-GNU-Fund

Der Befehl verwendet printf (verfügbar in GNU find ), die besagt find um seine Ergebnisse mit relativen Pfaden zu drucken. Wenn Sie jedoch nicht über GNU find funktioniert dies, um die Pfade relativ zu machen (entfernt die Eltern mit sed ):

find /my/dir/ -type f -o -type l -o -type d | sed s,^/my/dir/,, | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

39voto

Magnus Punkte 4544

Werfen Sie einen Blick auf --transform / --xform können Sie den Dateinamen massieren, wenn die Datei dem Archiv hinzugefügt wird:

% mkdir my_directory
% touch my_directory/file1
% touch my_directory/file2
% touch my_directory/.hiddenfile1
% touch my_directory/.hiddenfile2
% tar -v -c -f my_dir.tgz --xform='s,my_directory/,,' $(find my_directory -type f)
my_directory/file2
my_directory/.hiddenfile1
my_directory/.hiddenfile2
my_directory/file1
% tar -t -f my_dir.tgz 
file2
.hiddenfile1
.hiddenfile2
file1

Der Ausdruck transformieren ist ähnlich wie der von sed und wir können andere Trennzeichen verwenden als / ( , im obigen Beispiel).
https://www.gnu.org/software/tar/manual/html_section/tar_52.html

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