Melhor maneira de listar os 100 primeiros arquivos em um diretório classificado por hora

12

Qual seria a melhor maneira de listar 100 primeiros arquivos em um diretório classificado pelo carimbo de data / hora criado (o mais antigo primeiro). O diretório é bastante grande (cerca de 100000 arquivos).

ls canalizada para a cabeça leva um tempo muito longo para ser concluído.

Editar:

  • O sistema de arquivos é ext3.
  • limitar o número de arquivos na pasta não vale a pena, pois essa será uma operação rara de "limpeza" e os arquivos são gerados por um software de terceiros.
  • O uso da hora da modificação do arquivo , em vez da hora da criação, fornece uma solução aceitável.


fonte
1
Se for uma operação de limpeza, talvez o que você deseja seja apenas find -mtime +<number of days> -deletelimpar todos os arquivos com mais de uma certa idade. Isso significa que nenhum tipo é necessário.
Mikel

Respostas:

14

Você diz que " ls canalizada para a cabeça leva um tempo muito longo para completo".

A causa disso não é ls, mas o número de arquivos no seu diretório. Se você tiver 100.000 arquivos em um único diretório, qualquer maneira de resolver esse problema teria que obter informações sobre todos os 100.000 arquivos antes que pudesse pensar em classificá-los ou imprimir qualquer saída.

Se estiver demorando muito, a solução real é dividir os arquivos em vários diretórios.

Se você não pode distribuir os arquivos por vários diretórios, existe alguma maneira de diminuir o número de arquivos a serem considerados ? por exemplo, se os nomes dos arquivos incluírem uma data, talvez você possa incluir um curinga para que o sistema não precise classificar 100.000 arquivos. Ou talvez estejam numerados sequencialmente? (Isso pode ou não ajudar, mas vale a pena tentar.)

Quantas vezes você está tentando fazer isso? Talvez valha a pena salvar / armazenar em cache a saída para reutilização .


Agora, uma pergunta.

Tem certeza de que quer dizer "hora da criação" e não "hora da alteração" ? A maioria das ferramentas pode exibir apenas "hora de alteração", não "hora de criação".

Obter "tempo de criação" é algo muito novo, que requer um sistema de arquivos ext4 e algumas ferramentas que não são fáceis de instalar.


Se você quiser mudar o horário

Tempo de alteração (ctime para abreviar) significa o horário em que os atributos do arquivo foram alterados pela última vez.

ls -c classifica por ctime.

Você deseja a saída em ordem crescente, e não decrescente, portanto, você também deve inverter a saída com a -ropção

Então você poderia fazer assim:

ls -cr | head -n 100

Uma solução mais longa para o mesmo problema usando stat:

find . -mindepth 1 -maxdepth 1 -exec stat -c $'%Z\t%n' '{}' \; |
    sort -k 1n |
    cut -f 2 -d $'\t' |
    head -n 10 |
    sed -e 's/^\.\///'

mas isso corre mais devagar do que ls -crno meu sistema.


Se você deseja tempo de modificação

Hora da modificação (mtime para abreviar) significa a hora em que o conteúdo do arquivo foi alterado pela última vez.

ls -t classifica por mtime.

Mude ls -crpara ls -tr(melhor opção) ou mude stat -c $'%Z\t%n'para stat -c $'%Y\t%n'.


Se você precisar de tempo de criação

(tempo curto)

Isso é mais difícil.

Primeiro, verifique se o diretório está em um sistema de arquivos formatado usando ext4. Você pode usar tune2fs -l <device name>para verificar isso.

Depois, há um novo statformato chamado %W, que pode ajudá-lo aqui. Para obtê-lo, você precisará baixar uma versão do GNU Coreutils lançada em outubro de 2010 ou depois, extraí-la, compilá-la e instalá-la.

Então, dependendo do seu kernel, isso pode funcionar (ainda não tentei).

find . -mindepth 1 -maxdepth 1 -exec stat -c $'%W\t%n' '{}' \; |
    sort -k 1n |
    cut -f 2 -d $'\t' |
    head -n 10 |
    sed -e 's/^\.\///'

Veja também:


Se você receber erros sobre "'$\t'

A '$\t'notação requer bashou zsh: não funcionará no dashou shno Ubuntu. Se você realmente precisa usar essas conchas, você vai precisar alterar qualquer \tde Ctrl+ V, Tabe remova o líder $de um pouco antes da citação de abertura.

Mikel
fonte
É possível que ele não esteja executando o ext4. Eu corro o Ubuntu 10.04 em todas as minhas máquinas, mas corro o JFS em várias unidades. O AFAIK JFS suporta carimbos de data e hora de criação.
jwernerny
De fato. Sabemos que ele não é suportado no ext3 e é suportado no ext4. Uma pesquisa rápida sugere que ele pode funcionar com o zfs, ou o ufs do FreeBSD, mas nenhum deles é comum no Ubuntu! Não tenho certeza sobre jfs ou xfs ou qualquer outra coisa. Ficaria feliz em saber mais se você encontrar informações / links.
Mikel
Obrigado por essa resposta muito abrangente e pelo lembrete sutil de escrever perguntas mais específicas;) "Localizar" acabou sendo um vencedor em termos de desempenho e o tipo fs foi ext3.
2

Outra maneira, se encontrada de fazer as coisas hoje, pode ser relevante para os seus problemas de desempenho:

I=0; ls -cr /dir/ | while read file; do I=`expr $I + 1`; echo "$file"; if [ $I == 100 ]; then break; fi; done

Em teoria, isso deve começar a produzir muito mais rápido, mas acho que depende de onde o atraso está vindo. Pode levar lsum longo tempo para classificar os arquivos.

Oli
fonte
Eu duvido. headna verdade sai assim que lê bastante entrada. Tente executar os dois com timena frente. A headversão é muito mais rápida no meu sistema de qualquer maneira.
Mikel