Resultado de uma localização 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
e quando classificado com sort -n
:
./as/002-mod.txt
./tool/000-main.txt
./tool/001-sub.txt
./zo/001-int.txt
./zo/id/002-and.txt
no entanto, a saída desejada é:
./tool/000-main.txt
./zo/001-int.txt
./tool/001-sub.txt
./zo/id/002-and.txt
./as/002-mod.txt
o que significa que a saída é classificada com base apenas no nome do arquivo , mas as informações da pasta devem ser mantidas como parte da saída.
Editar : Tornar o exemplo mais complicado, pois a estrutura do subdiretório pode incluir mais de um nível.
-printf
vez deawk
), acho que essa é a melhor solução. Eu refiz a minha implementação original para usar esse método.Respostas:
Você precisa classificar pelo último campo (considerando
/
como um separador de campos). Infelizmente, não consigo pensar em uma ferramenta que possa fazer isso quando o número de campos varia (se ao menossort -k
pudéssemos assumir valores negativos).Para contornar isso, você terá que fazer uma decoração-classificar-undecorate. Ou seja, pegue o nome do arquivo e coloque-o no início, seguido por um separador de campos, faça uma classificação e remova a primeira coluna e separador de campos.
Esse
awk
comando diz que o separador de campoFS
está definido como/
; isso afeta a maneira como ele lê os campos. O separador de campos de saídaOFS
também está definido como/
; isso afeta a maneira como imprime registros. A próxima instrução diz imprime a última coluna (NF
é o número de campos no registro, portanto também é o índice do último campo), bem como o registro inteiro ($0
é o registro inteiro); irá imprimi-los com o OFS entre eles. Em seguida, a lista ésort
editada, tratando/
como separador de campos - já que temos o nome do arquivo primeiro no registro, ele será classificado por isso. Em seguida, ascut
impressões são impressas apenas nos campos 2 até o final, tratando novamente/
como o separador de campos.fonte
-printf '%f/%p\n'
Eu usaria os arquivos '-printf' para gerar o nome e o caminho, classificar por nome e cortar o nome em uma última etapa. '###' é apenas um marcador para ajudar no corte.
% f imprime o nome do arquivo,% p o caminho inteiro.
Simplifiquei o comando find para colocá-lo em uma linha, é claro que você deixaria a
! -path "./build*"
peça.fonte
No zsh ≥4.3.10:
**/*.txt
corresponde*.txt
no diretório atual e seus subdiretórios recursivamente .~build*
exclui correspondências cujo texto começa combuild*
(como! -path './build*'
). (Você precisasetopt extended_glob
primeiro.)(oe\''…'\')
é um qualificador glob de classificação .REPLY=…
constrói a sequência a ser classificada a partir da sequência a ser retornada.${REPLY:t}
é o nome da base ("cauda") do caminho.fonte