Wie tariere ich Dateien mit einer sortierten Reihenfolge?

10

Wenn Sie tarein Verzeichnis rekursiv erstellen, wird nur die Reihenfolge aus dem Betriebssystem verwendet readdir.

Aber in einigen Fällen ist es schön, die Dateien sortiert zu tarieren.

Was ist ein guter Weg, um ein alphabetisch sortiertes Verzeichnis zu tarieren?


Beachten Sie, dass für die Zwecke dieser Frage gnu-tar auf einem typischen Linux-System in Ordnung ist.

ideasman42
quelle
möglich Duplikat unten, Unten finden Sie Links unix.stackexchange.com/questions/120143/... superuser.com/questions/172367/...
Jaymin Dabhi
Ich habe das gesehen, aber ich frage nicht, wie die Reihenfolge festgelegt ist, sondern ich möchte sie sortieren.
ideasman42
Siehe auch unix.stackexchange.com/a/67018 zum Sortieren eines Verzeichnisbaums nach Namen.
Stéphane Chazelas

Antworten:

17

Für eine GNU tar:

--sort=ORDER
 Specify the directory sorting order when reading directories.
 ORDER may be one of the following:

`none'
      No directory sorting is performed. This is the default.

`name'
      Sort the directory entries on name. The operating system may
      deliver directory entries in a more or less random order, and
      sorting them makes archive creation reproducible.

`inode'
      Sort the directory entries on inode number. Sorting
      directories on inode number may reduce the amount of disk
      seek operations when creating an archive for some file
      systems.

Sie werden wahrscheinlich auch schauen wollen --preserve-order.

mikeserv
quelle
8
--sortwurde in tar version 1.28 eingeführt. --preserve-orderist für diese Frage nicht relevant.
Mhsmith
Ich habe immer wieder tar: Exiting with failure status due to previous errorsFehler. @mhsmith
alper
3

Mit zshstatt:

pax -w dir

Verwenden:

pax -dw dir dir/**/*(D)

Sie können dasselbe mit aktuellen Versionen von bash -O globstar -O dotglobwith tun :

pax -dw dir/**

Oder aktuelle Versionen von FIGNORE='@(.|..)' ksh93 -o globstarmit:

pax -dw dir dir/**

paxist der Standardbefehl zum Erstellen von tarDateien. Die Ausgabe geht an stdout. Shell-Globs werden nach Namen sortiert.

Wenn Sie auf einen zu langen Fehler in der Arg-Liste stoßen, können Sie zu Folgendem wechseln:

printf '%s\0' dir dir/**/*(D) | pax -0dw

(Nicht alle paxImplementierungen unterstützen -0jedoch).

Stéphane Chazelas
quelle
2

tarselbst kann dies nicht, daher müssen Sie es aus einer korrekt geordneten Liste erstellen. Im Prinzip könnte man dann verwenden tar‚s -TOption, aber es gibt keine Möglichkeit, festzulegen , dass die Dateinamen in dieser Liste sollen beendet werden NUL. Wenn Sie also Dateinamen mit Zeilenumbrüchen haben (was zulässig ist), wird dies nur unterbrochen.

Eine bessere Option ist das cpioGenerieren der Dateien, da diese eine NUL-terminierte Liste von Dateinamen akzeptieren und TAR-Dateien generieren können.

Wenn Ihr tarBefehl wäre:

tar cvf /somedir/all.tar .

Damit dies nach Namen sortiert werden kann, müssten Sie Folgendes tun (unter der Annahme von GNU find und cpio):

find . -type f -print0 | sort -z | \
  cpio --create --null --format=ustar -O /somedir/all.tar

Dies hat jedoch den Nachteil, dass Unterverzeichnisse zwischen Dateinamen platziert werden. Sie können Tricks mit finds -printf0 ausführen, indem Sie die Verzeichnis- und Tiefeninformationen angeben und mit sortieren. Dies sort -nbeeinflusst jedoch auch, wie Dateien mit Nummern innerhalb eines Verzeichnisses sortiert werden.

Wenn das oben os.walk()Genannte nicht zufriedenstellend ist, können Sie wahrscheinlich ein kleines Python-Programm verwenden, das auf basiert , um die gewünschte Reihenfolge mit voller Kontrolle zu generieren (Tiefe zuerst, basierend auf Erweiterung usw.), aber wenn Sie diesen Weg gehen, können Sie das auch fallen lassen cpiound ausschreiben tarDatei mit Python- tarfileModul.

Anthon
quelle
1
--null gibt an, dass -T nullterminierte Zeichenfolgen akzeptiert.
Psusi