Résultat d'une recherche normale utilisant 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
et lorsqu'il est trié avec sort -n
:
./as/002-mod.txt
./tool/000-main.txt
./tool/001-sub.txt
./zo/001-int.txt
./zo/id/002-and.txt
cependant, la sortie souhaitée est:
./tool/000-main.txt
./zo/001-int.txt
./tool/001-sub.txt
./zo/id/002-and.txt
./as/002-mod.txt
ce qui signifie que la sortie est triée en fonction du nom de fichier uniquement , mais les informations de dossier doivent être conservées dans le cadre de la sortie.
Edit : rendre l'exemple plus compliqué car la structure du sous-répertoire peut inclure plus d'un niveau.
-printf
plutôt queawk
), je pense que c'est la meilleure solution. J'ai retravaillé mon implémentation d'origine pour utiliser cette méthode.Réponses:
Vous devez trier par le dernier champ (considéré
/
comme un séparateur de champ). Malheureusement, je ne peux pas penser à un outil qui puisse le faire lorsque le nombre de champs varie (si seulementsort -k
pouvait prendre des valeurs négatives).Pour contourner cela, vous devrez faire une déco-décorer-décorer. Autrement dit, prenez le nom de fichier et placez-le au début suivi d'un séparateur de champ, puis effectuez un tri, puis supprimez la première colonne et le séparateur de champ.
Cette
awk
commande indique que le séparateur de champFS
est défini sur/
; cela affecte la façon dont il lit les champs. Le séparateur de champ de sortieOFS
est également défini sur/
; cela affecte la façon dont il imprime les enregistrements. L'instruction suivante indique imprimer la dernière colonne (NF
est le nombre de champs dans l'enregistrement, donc il se trouve que c'est également l'index du dernier champ) ainsi que l'enregistrement entier ($0
est l'enregistrement entier); il les imprimera avec l'OFS entre eux. Ensuite, la liste estsort
éditée, en/
tant que séparateur de champ - puisque nous avons le nom de fichier en premier dans l'enregistrement, il sera trié en fonction de cela. Ensuite, lecut
champ imprime uniquement les champs 2 jusqu'à la fin et est à nouveau traité/
comme le séparateur de champ.la source
-printf '%f/%p\n'
J'utiliserais les fichiers '-printf' pour sortir le nom et le chemin, trier par nom et couper le nom dans une dernière étape. '###' est juste un marqueur, pour aider à couper.
% f imprime le nom du fichier,% p le chemin complet.
J'ai simplifié la recherche de commande pour la mettre sur une seule ligne, bien sûr, vous quitteriez la
! -path "./build*"
partie.la source
En zsh ≥4.3.10:
**/*.txt
correspond*.txt
dans le répertoire courant et ses sous-répertoires de manière récursive .~build*
exclut les correspondances dont le texte commence parbuild*
(comme! -path './build*'
). (Vous devez d'setopt extended_glob
abord.)(oe\''…'\')
est un qualificateur de glob de tri .REPLY=…
construit la chaîne à trier à partir de la chaîne à renvoyer.${REPLY:t}
est le nom de base («queue») du chemin.la source