Localizar e classificar nomes de arquivos numéricos

2

Eu estou tentando encontrar arquivos que correspondem a time=* e, em seguida, preciso exibi-lo, classificando-o numericamente.
Os nomes dos arquivos de resultado seriam:

first/path/time=001.jpg
first/path/time=002.jpg
second/path/time=001.jpg
...

que eu quero ver como,

first/path/time=001.jpg
second/path/time=001.jpg
first/path/time=002.jpg
...

ordenada numericamente em relação aos 3 dígitos no nome do arquivo.

Por enquanto, eu tentei find . -name time=* | rev | sort | rev

que funciona para dígitos únicos, mas com números como 019 021 , não funciona.

Caminho completo seria algo como

path/to/folder1/alpha=0.1_beta=0.2_gamma=1.0/time=001.jpg
path/to/folder1/alpha=0.1_beta=0.2_gamma=0.1/time=001.jpg
path/to/folder2/alpha=0.1_beta=0.2_gamma=0.1/time=001.jpg
.
.
.

Acho que seria mais fácil se os arquivos pudessem ser classificados usando apenas os últimos 7 caracteres. 001.jpg 010.jpg ... no entanto, infelizmente sort não suporta a indexação negativa de suporte para obter os 6 últimos caracteres: (

    
por hadi k 23.01.2018 / 11:07

3 respostas

2

Isso deve ser feito:

find . -name 'time=*' | sort -t= -k3

Mas esta é uma classificação mais segura, de acordo com o comentário de Kamil Maciorowski:

perl -C -F= -wnle 'push @a,[$_,split(/\./,$F[-1])]; END {$,="\n"; print map{$$_[0]} sort{$$a[1]<=>$$b[1]} @a}'

Use no pipeline afer find em vez de sort no primeiro.

    
por 23.01.2018 / 13:29
2

Supondo que nenhum caminho seja insano o suficiente para exigir find ... -print0 :

find . -type f -name "time=*" | awk -F '=' '{ print $NF "=" $0 }' | sort -n | cut -d "=" -f 2-

Eu usei awk para extrair partes atrás do último = , ele exibe linhas completas com adicional parte relevante na frente, separando por adicionais = . Por exemplo:

001.jpg=path/to/folder1/alpha=0.1_beta=0.2_gamma=1.0/time=001.jpg

Eles são classificados numericamente com sort . Em seguida, cut extrai partes após este (primeiro)% adicional=; estes são os caminhos originais.

Existem exatamente quatro processos criados: find , awk , sort , cut . As alternativas que usam a sintaxe de find ... -exec some_tool ... \; criam um some_tool process por arquivo correspondente.

    
por 23.01.2018 / 15:03
1

Uma rapidinha com as sobras que escolhi na linha de comando: -)

find . -name time="*" -exec ruby -e "s='{}'; puts s.split('=')[-1].split('.')[0]+s" \; |
sort -n | colrm 1 3

Explicação:

Meu amigo Ruby armazena a string de caminho dada por find como {} e a armazena em uma variável s . Em seguida, ela divide a string ao longo de = caracteres e mantém a última parte (índice -1 na matriz de resultados), por ex. %código%. Em seguida, ela divide essa string em 002.jpg caracteres e mantém a primeira parte (índice 0 na matriz resultante), presumindo que os arquivos tenham o nome . , cujos resultados são a parte numérica de três dígitos, por exemplo. %código%.

Por fim, ela imprime isso e adiciona a string do caminho original. Isso daria:

002./alpha=0.1_beta=0.2_gamma=1.0/path/time=002.jpg
001./alpha=0.1_beta=0.2_gamma=1.0/path/time=001.jpg
021./alpha=0.1_beta=0.2_gamma=0.1/path/time=021.jpg
001./alpha=0.1_beta=0.2_gamma=0.1/path/time=001.jpg
019./alpha=0.1_beta=0.2_gamma=0.1/path/time=019.jpg

Os comandos de canal adicionais classificam a saída numericamente ( ddd.<ext> ) e, finalmente, removem as três primeiras colunas da saída ( 002 ).

Exemplo:

test$ find . -name time="*" -exec ruby -e "s='{}'; puts s.split('=')[-1].split('.')[0]+s" \; 
| sort -n | colrm 1 3
./alpha=0.1_beta=0.2_gamma=0.1/path/time=001.jpg
./alpha=0.1_beta=0.2_gamma=1.0/path/time=001.jpg
./alpha=0.1_beta=0.2_gamma=1.0/path/time=002.jpg
./alpha=0.1_beta=0.2_gamma=0.1/path/time=019.jpg
./alpha=0.1_beta=0.2_gamma=0.1/path/time=021.jpg
    
por 23.01.2018 / 11:46