
Ich habe folgende Verzeichnisstruktur:
test/
test/1/
test/foo2bar/
test/3/
Ich möchte das Verzeichnis "test" komprimieren und dabei alles aus Unterverzeichnissen ausschließen (Tiefe nicht vordefiniert), die die Zeichenfolgen "1" oder "2" enthalten. In der Bash-Shell möchte ich verwendenfindenund leiten Sie die Ausgabe anTeerIch teste zuerstfinden:
find test/ -not -path "*1*" -not -path "*2*"
Ausgabe:
test/
test/3
Super. Also kombiniere ich es mitTeer:
find test/ -not -path "*1*" -not -path "*2*" | tar -czvf test.tar.gz --files-from -
Ausgabe:
test/
test/3/
test/1/
test/foo2bar/
test/3/
Tatsächlich sind sowohl „test/1“ als auch „test/foo2bar“ im Archiv vorhanden.Warum wurden diese Argumente an tar übergeben, wenn sie in der Find-Ausgabe nicht vorhanden sein sollten?
Antwort1
Um auf das einzugehen, was @cuonglm gesagt hat: tar
standardmäßig funktioniert es rekursiv. Wenn Sie ihm einen Verzeichnisnamen übergeben, wird es das archivierenInhaltdieses Verzeichnisses.
Sie könnten Ihren find
Befehl so ändern, dass er nur die Namen der Dateien und nicht der Verzeichnisse zurückgibt ...
find test/ -type f -not -path "*1*" -not -path "*2*" |
tar -czvf test.tar.gz --files-from -
Sie können die --no-recursion
Flagge stattdessen für Folgendes verwenden tar
:
find test/ -not -path "*1*" -not -path "*2*" |
tar -czvf test.tar.gz --no-recursion --files-from -
Was dazu führt:
test/
test/3/
Das --no-recursion
Flag ist spezifisch für GNU Tar. Wenn Sie etwas anderes verwenden, prüfen Sie auf der entsprechenden Manpage, ob eine ähnliche Funktion verfügbar ist.
Beachten Sie, dass Ihr find
Befehl ausschließtDateien1
die oder 2
im Pfad sowie in Verzeichnissen enthalten .
Antwort2
Mit GNU Tar können Sie auch die --exclude
Option nutzen, Dateien basierend auf ihrem Namen auszuschließen.
$ tar --exclude "*1*" --exclude "*2*" -cvf foo.tar test/
test/
test/3/
Es gibt auch -X
oder --exclude-from
, das eine Datei verwendet, aus der die Ausschlussmuster gelesen werden.
Allerdings find -not -path "*1*"
werden dadurch auch Dateien ausgeschlossen, deren Namen ein 1
oder enthalten 2
. Um nur Dateien zu überspringen,Verzeichnissederen Namen dem Muster entsprechen, verwenden Sie find -prune
und tar --no-recursion
:
$ touch test/3/blah.1
$ find test/ -type d \( -name "*1*" -o -name "*2*" \) -prune -o -print |
tar cvf test.tar --files-from - --no-recursion
test/
test/3/
test/3/blah.1
(Zumindest GNU Tar und FreeBSD Tar haben dies --no-recursion
)