Resultado de un hallazgo normal usando 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
y cuando se ordena con sort -n
:
./as/002-mod.txt
./tool/000-main.txt
./tool/001-sub.txt
./zo/001-int.txt
./zo/id/002-and.txt
sin embargo, la salida deseada es:
./tool/000-main.txt
./zo/001-int.txt
./tool/001-sub.txt
./zo/id/002-and.txt
./as/002-mod.txt
lo que significa que la salida se ordena solo en nombre de archivo , pero la información de la carpeta debe mantenerse como parte de la salida.
Editar : Haga que el ejemplo sea más complicado ya que la estructura del subdirectorio puede incluir más de un nivel.
-printf
lugar deawk
), creo que esa es la mejor solución. He revisado mi implementación original para usar este método.Respuestas:
Debe ordenar por el último campo (considerando
/
como un separador de campo). Desafortunadamente, no puedo pensar en una herramienta que pueda hacer esto cuando la cantidad de campos varía (si solosort -k
pudiera tomar valores negativos).Para evitar esto, tendrás que hacer una decoración-ordenar-decorar. Es decir, tome el nombre del archivo y póngalo al principio seguido de un separador de campo, luego haga una ordenación, luego elimine la primera columna y el separador de campo.
Ese
awk
comando dice que el separador de campoFS
está configurado en/
; Esto afecta la forma en que lee los campos. El separador de campo de salidaOFS
también se establece en/
; Esto afecta la forma en que imprime los registros. La siguiente declaración dice imprimir la última columna (NF
es el número de campos en el registro, por lo que también es el índice del último campo), así como el registro completo ($0
es el registro completo); los imprimirá con la OFS entre ellos. Luego se edita la listasort
, que se trata/
como el separador de campo, ya que tenemos el nombre de archivo primero en el registro, se ordenará por eso. Luego, lascut
impresiones solo los campos 2 hasta el final, nuevamente se tratan/
como el separador de campo.fuente
-printf '%f/%p\n'
Usaría los archivos '-printf' para generar el nombre y la ruta, ordenar por nombre y cortar el nombre en un último paso. '###' es solo un marcador, para ayudar a cortar.
% f imprime el nombre del archivo,% p la ruta completa.
Simplifiqué el comando de búsqueda para ponerlo en una línea, por supuesto, dejarías la
! -path "./build*"
parte.fuente
En zsh ≥4.3.10:
**/*.txt
coincide*.txt
en el directorio actual y sus subdirectorios de forma recursiva .~build*
excluye coincidencias cuyo texto comienza conbuild*
(me gusta! -path './build*'
). (Necesitassetopt extended_glob
primero)(oe\''…'\')
es un calificador global de clasificación .REPLY=…
construye la cadena para ordenar de la cadena para devolver.${REPLY:t}
es el nombre base ("cola") de la ruta.fuente