Como listar arquivos em uma ordem específica de acordo com o diretório no bash?

0

Eu tenho um monte de diretórios, cada um contendo um monte de arquivos. Normalmente eu posso listar todos os arquivos com ls */*.* mas isso sempre os lista de acordo com a ordem alfabética nos diretórios e, em seguida, na ordem alfabética dentro de cada diretório. Então sempre será produzido

dir1 / file1.foo
dir1 / file2.foo
...
dir2 / file1.foo
dir2 / file2.foo
...
...
dirN / file1.foo
dirN / file2.foo
...

O que eu gostaria que fizesse é enviar os diretórios para que eles sejam organizados em uma ordem específica (por exemplo, ao contrário), mas com todos os arquivos dentro de cada diretório em ordem normal, assim:

dirN / file1.foo
dirN / file2.foo
...
...
dir1 / file1.foo
dir1 / file2.foo
...

Usar ls -r */*.* não faz o que eu quero porque inverte a ordem dentro de cada diretório, bem como a ordem dos próprios diretórios. Eu tentei usar ls 'ls -r' que faz o que eu quero para os nomes de diretório que não têm espaços neles, mas não funciona para os que fazem (o que é, infelizmente, a maioria deles). Se eu tentar, em vez disso, ls "'ls -r'" , a saída será a mesma coisa que ls -r - uma lista de nomes de diretórios, mas em sentido inverso. Como faço para fazer o que eu quero?

    
por Dillon Ethier 12.06.2017 / 23:13

3 respostas

1

Usando o comando sort :

ls */* | sort -rst '/' -k1,1

com:

  • -t '/' para alterar o separador de campos
  • -r para fazer uma ordenação inversa
  • -s para garantir que a classificação seja estável (em outras palavras, não altera a ordem além das colunas especificadas
  • -k1,1 para restringir a classificação à primeira coluna

Isso pressupõe que a saída de ls */* já esteja classificada (o que deveria ser), caso contrário, adicione um estágio sort simples no meio.

    
por 12.06.2017 / 23:53
0

via script zsh

Como na maioria das coisas no Linux / Unix, existe mais do que uma maneira de fazer as coisas. Para melhor ou pior, e para o que vale a pena, essa é outra maneira de fazer a mesma coisa.

#!/usr/bin/env zsh
Dirs=(*(/D))  # (/D) = /(only directories) D(include hidden or dot)
for D in ${(O)Dirs}  # (O) = reverse sort
do
    L=(${D}/*(ND))  # (ND) = N(in case the glob is empty) D(see above)
    [ ${#L} -eq 0 ] && { print "${D}/" ; continue }  # if empty glob
    print -l ${(o)L}  # (o) = normal sort
done

print zsh incorporado em -l produz cada elemento em sua própria linha.

Deixe de fora o qualificador D glob se você não quiser listar diretórios e arquivos ocultos.

zsh

    
por 18.06.2017 / 20:48
0

Complementando a resposta do @xeniod (iniciada como um comentário, mas ficou muito longa): de acordo com o requisito original de ordenar diretórios ao contrário e arquivos em ordem alfanumérica:

$ ls -d */* | sort -s -t '/' -k1,1rn -k2,2

Ou, se os arquivos / diretórios tiverem mais de um dígito, por exemplo, em vez de apenas dir1..dir9 , você também terá dir10, dir11, dir101,... e arquivos file1..file10..file101... , poderá classificar como "números de versão" usando a opção -V vs apenas alpha / numeric sort (apenas suportado na classificação GNU):

$ ls -d */* | sort -s -t '/' -k1,1rV -k2,2V

Idealmente, porém, seus diretórios e amp; os arquivos terão alguns caracteres especiais prefixando (ou delimitando) os campos que você deseja classificar como um traço (" - "), por exemplo, dir-23/file-1.txt , dir-902/file-203.txt , etc, para poder classificar apenas nesses campos ( texto não numérico após o número ser ignorado):

$ ls -d */* | sort -s -t- -k2,2nr  -k3,3n

Pontos principais:

  • adicione vários -k{begin,end} para classificar colunas entre delimitadores / separadamente, por exemplo, classificar primeira coluna como alfanumérica, segunda como inversa numérica, terceira como "números de versão", etc
  • Eu adicionei " -d " a " ls -d */* ", para que o conteúdo do diretório não seja listado, o que quebrará a classificação, se existirem. Alternativamente, para somente considerar arquivos, poderia usar find */ -maxdepth 1 -type f em vez de ls .
  • Note que você nem se importa com "/" no seu tipo, o que geralmente é bom. Note que você não pode ter mais de um -t {delim} em uma única classificação de qualquer maneira (por exemplo, -t '-' -k... -t '/'... )
por 19.06.2017 / 03:22