Como ordenar nomes de arquivos em ordem numérica E ordem de tempo modificada?

4

Eu quero juntar arquivos pdf por pdfjoin / pdfunite / ... na ordem numérica discutida bem na resposta do tópico comando linux mescla arquivos pdf com ordenação numérica e ordem de tempo Modificada . Se você usar a solução no encadeamento, ela coloca a ordem em ordem numérica e ordem alfabética. Isso é problemático com os nomes de arquivos como o que você vê, ambos têm o mesmo tempo modificado por precisão de minuto, mas Visceral é anterior pela segunda precisão (navegador de arquivos o anota e coloca Visceral primeiro na ordem Modified .

Filename               Modified
-----                  ---
3.THE ABC.pdf          10:39 
3.Visceral abc..pdf    10:39

Preencha os nomes dos arquivos

1.Description abc.pdf
2.Gabcd.pdf
3.THE ABC.pdf
3.Visceral abc..pdf
4.description of abc.pdf
5.Chraa..pdf

A Proposta # 1 funciona na ordem numérica e alfabética, mas não na ordem numérica e modificada

# https://stackoverflow.com/a/23643544/54964
ls -v *.pdf | ...
    bash -c 'IFS=$'"'"'\n'"'"' read -d "" -ra x;pdfunite "${x[@]}" output.pdf'

O caso simplificado da proposta nº 2, mas não trata espaços em branco e outros caracteres especiais em nomes de arquivos

# https://stackoverflow.com/a/23643544/54964
pdfunite $(ls *.pdf | sort -n) output.pdf

Não há nada no pdfunite --help sobre o pedido, então acho que isso deve ser feito por ls / sort / ... O comando sort não tem nada sobre modified em sua página man.

Testando a resposta de xhienne

O pedido não está correto na saída em que você vê 2.jpg e 4.jpg estão na ordem errada por algum motivo

masi@masi:~/Documents$ ls -tr /home/masi/Documents/[0-9]* | sort -t. -k1,1n -s
/home/masi/Documents/1.jpg
/home/masi/Documents/3.jpg
/home/masi/Documents/5.jpg
/home/masi/Documents/6.jpg
/home/masi/Documents/7.jpg
/home/masi/Documents/8.jpg
/home/masi/Documents/9.jpg
/home/masi/Documents/10.jpg
/home/masi/Documents/2.jpg
/home/masi/Documents/4.jpg

2ª iteração

export LC_ALL=C; ls -tr /home/masi/Documents/[0-9]* | sort -t. -k1,1n -s

Saída

/home/masi/Documents/1.jpg
/home/masi/Documents/3.jpg
/home/masi/Documents/5.jpg
/home/masi/Documents/6.jpg
/home/masi/Documents/7.jpg
/home/masi/Documents/8.jpg
/home/masi/Documents/9.jpg
/home/masi/Documents/10.jpg
/home/masi/Documents/2.jpg
/home/masi/Documents/4.jpg

OS: Debian 8.5

    
por Léo Léopold Hertz 준영 23.12.2016 / 10:31

3 respostas

5

Você pode fazer isso com zsh :

zmodload zsh/stat

prefixmtime () {
sortstring=${(l:6::0:)${REPLY%%.*}}$(zstat -F '%s' +mtime -- $REPLY)
REPLY=${sortstring}
}

print -rl -- *(o+prefixmtime)

Substitua print -rl pelo seu comando se estiver satisfeito com o resultado

Como funciona:
Os globs irão classificar aqui (via o+function ) com base no que a função prefixmtime retorna, ou seja, sortstring , que é uma string obtida pela concatenação do prefixo numérico de cada nome de arquivo ${REPLY%%.*} left- preenchidos com zeros (l:6::0:) (supondo que os prefixos tenham até 6 caracteres) e os mtime em segundos (obtidos por meio de zstat module). Pode ser mais fácil entender como funciona se você executar:

{ for f (*)
printf '%s %s\n' ${(l:6::0:)${f%%.*}}$(zstat -F '%s' +mtime -- $f) $f
} | sort -k1,1n

Note que o acima assume que você está no mesmo diretório com seus arquivos, caso contrário você terá que definir a string de classificação nessa função como

sortstring=${(l:6::0:)${${REPLY##*/}%%.*}}$(zstat -F '%s' +mtime -- $REPLY)

e, em seguida, você pode usar caminhos de diretório, por exemplo,

print -rl some/place/else/*(o+prefixmtime)
    
por 23.12.2016 / 16:08
4
find /home/masi/Documents -maxdepth 1 -type f -name '[0-9]*' -printf "%T+ %f\n" | sort -k2n -k1,1| cut -d ' ' -f 2- | xargs -i echo pdfunite /home/masi/Documents/{} output.pdf

Isso não manipulará novas linhas em nomes de arquivos.

Você pode alternar a reversão das ordens de classificação alterando -k1,1 para -k1,1r , o que reverterá a classificação do tempo e -k2nr reverterá a classificação do nome do arquivo.

    
por 23.12.2016 / 16:10
2

A solução é classificar primeiro por tempo de modificação, depois classificar apenas no primeiro campo numérico (assumindo que os campos estão separados por '.') enquanto desativa a última comparação de recurso (também conhecido como classificação estável ).

ls -tr [0-9]* | sort -t. -k1,1n -s

[atualização]

Como você parece ter espaços em branco nos seus nomes de arquivos, você deve usar xargs para executar pdfunite :

ls -tr [0-9]* | ( sort -t. -k1,1n -s; echo output.pdf ) | xargs pdfunite
    
por 23.12.2016 / 12:34

Tags