Ergebnis eines normalen Funds mit find . ! -path "./build*" -name "*.txt"
:
./tool/001-sub.txt
./tool/000-main.txt
./zo/001-int.txt
./zo/id/002-and.txt
./as/002-mod.txt
und wenn sortiert mit sort -n
:
./as/002-mod.txt
./tool/000-main.txt
./tool/001-sub.txt
./zo/001-int.txt
./zo/id/002-and.txt
Die gewünschte Ausgabe ist jedoch:
./tool/000-main.txt
./zo/001-int.txt
./tool/001-sub.txt
./zo/id/002-and.txt
./as/002-mod.txt
Dies bedeutet, dass die Ausgabe nur nach dem Dateinamen sortiert wird, die Ordnerinformationen jedoch als Teil der Ausgabe beibehalten werden sollten.
Bearbeiten : Machen Sie das Beispiel komplizierter, da die Unterverzeichnisstruktur mehr als eine Ebene enthalten kann.
-printf
anstelle von verwendenawk
), halte ich dies für die beste Lösung. Ich habe meine ursprüngliche Implementierung überarbeitet, um diese Methode zu verwenden.Antworten:
Sie müssen nach dem letzten Feld sortieren (als
/
Feldtrennzeichen betrachtet). Leider kann ich mir kein Tool vorstellen, das dies kann, wenn die Anzahl der Felder variiert (wenn nursort -k
negative Werte angenommen werden könnten).Um dies zu umgehen, müssen Sie ein Dekorieren-Sortieren-Undekorieren durchführen. Nehmen Sie den Dateinamen und setzen Sie ihn an den Anfang, gefolgt von einem Feldtrennzeichen. Führen Sie dann eine Sortierung durch und entfernen Sie die erste Spalte und das Feldtrennzeichen.
Dieser
awk
Befehl besagt, dass das Feldtrennzeichen auf gesetztFS
ist/
. Dies wirkt sich auf die Art und Weise aus, wie Felder gelesen werden. Das AusgabefeldtrennzeichenOFS
ist ebenfalls auf eingestellt/
. Dies wirkt sich auf die Art und Weise aus, wie Datensätze gedruckt werden. Die nächste Anweisung besagt, dass die letzte Spalte (NF
die Anzahl der Felder im Datensatz, also zufällig auch der Index des letzten Felds) sowie der gesamte Datensatz ($0
der gesamte Datensatz) gedruckt werden sollen. es druckt sie mit dem OFS zwischen ihnen. Dann wird die Listesort
bearbeitet und/
als Feldtrennzeichen behandelt. Da wir den Dateinamen zuerst im Datensatz haben, wird er danach sortiert. Danncut
druckt/
das Feld nur die Felder 2 bis zum Ende aus und wird erneut als Feldtrennzeichen behandelt.quelle
-printf '%f/%p\n'
Ich würde Dateien '-printf' verwenden, um Name und Pfad auszugeben, nach Namen zu sortieren und den Namen in einem letzten Schritt abzuschneiden. '###' ist nur ein Marker, um das Schneiden zu erleichtern.
% f gibt den Dateinamen aus,% p den gesamten Pfad.
Ich habe den Befehl find vereinfacht, um ihn in eine Zeile zu bringen. Natürlich würden Sie das
! -path "./build*"
Teil verlassen .quelle
In zsh ≥4.3.10:
**/*.txt
Übereinstimmungen*.txt
im aktuellen Verzeichnis und seinen Unterverzeichnissen rekursiv .~build*
schließt Übereinstimmungen aus, deren Text mitbuild*
(like! -path './build*'
) beginnt . (Du brauchstsetopt extended_glob
zuerst.)(oe\''…'\')
ist ein Sorting Glob Qualifier .REPLY=…
Konstruiert die zu sortierende Zeichenfolge aus der zurückzugebenden Zeichenfolge.${REPLY:t}
ist der Basisname ("Schwanz") des Pfades.quelle