Classificando ls por hora, quando há muitos arquivos para uma única invocação

5

Eu sei que posso classificar a saída de ls por tempo com a opção -t .

Eu sei que quando eu tenho tantos arquivos que eles não se encaixam em uma única invocação de ls , eu normalmente posso usar xargs (ou find ... -exec ... {} + ) para deixar ls ser chamado várias vezes. / p>

Como posso combinar os dois? Eu tenho mais arquivos do que caber na linha de comando e desejo listá-los por hora. find . -type f -exec ls -t {} + não funciona, porque supondo que exatamente 1000 nomes de arquivo caibam na linha de comando, e 3000 arquivos estão presentes, isso executará ls -t [first 1000 files]; ls -t [second 1000 files]; ls -t [last 1000 files] , onde os últimos 1000 arquivos find vê podem ter um tempo de modificação antes qualquer um dos primeiros 1000. Não parece que algo envolvendo xargs ou equivalente tenha qualquer chance de trabalho, parece que essa abordagem é fundamentalmente falha, mas não consigo encontrar uma maneira que faça trabalho.

    
por hvd 11.08.2014 / 09:15

3 respostas

9

ls -t por si só listará todos os arquivos no diretório atual com essa classificação , sem nunca precisar listá-los na linha de comando.

Se você precisar do comportamento de recursão de find ou de fazer outros testes nos arquivos, poderá ter find gerar entradas de registro de data e hora, por meio de stat ou% GNU find 'co_de% opção e classificá-lo. Algo como:

find . -type f -printf '%T@ %p
find . -type f -printf '%T@ %p%pre%' | sort -zn
' | sort -zn

-printf gera registro de data e hora Unix separado por nulo ( -printf '%T@ %p%T@' ) - nome do arquivo ( %p ) pares. O sort -z também é uma extensão GNU não padrão, que usa registros delimitados por nulos para serem protegidos por nomes de arquivos. A opção sort é suportada na maioria dos BSDs também, mas -printf é somente GNU até onde eu sei.

Você pode recortar essa saída apenas em nomes de arquivos ou em qualquer outro formato que desejar.

    
por 11.08.2014 / 09:31
3

Você pode usar find com perl Posixly:

$ find ! -name . -prune -print | perl -lne '
    $h{$_} = -M;
    END { print for sort {$h{$a} <=> $h{$b}} keys %h }
'

Isso pressupõe que você não tenha um caractere de nova linha no seu nome de arquivo.

Para lidar com a nova linha, você pode:

$ find ! -name . -prune -exec printf "%s
$ find ! -name . -prune -print | perl -lne '
    $h{$_} = -M;
    END { print for sort {$h{$a} <=> $h{$b}} keys %h }
'
" {} + | perl -0lne ...

ou use perl -le then split /%code%/,<> em seu código.

    
por 11.08.2014 / 11:50
3

No zsh:

print -rl -- *(om)

O qualificador de glob om classifica os arquivos por hora de modificação (ordem cronológica inversa , ou seja, o mais novo primeiro, como ls -t ). Use Om para obter a ordem oposta (ordem cronológica, como ls -tr ). Faça este *(Dom) incluir arquivos de ponto.

É claro que você pode variar o padrão , por exemplo, **/*(Dom) para recursar em subdiretórios. Se você quiser usar vários padrões, coloque-os entre parênteses e use o operador | para separá-los, por exemplo, *.(png|jpg)(om) .

Como print é um shell interno, esse comando não é afetado pelo limite máximo de comprimento da linha de comando. Se você quiser chamar um comando externo para atuar nos arquivos em lotes e na ordem, você terá o limite de tamanho. Você pode usar printf '%szargs' *(om) | xargs -0 somecommand para alimentar os arquivos para xargs se o seu xargs suportar entrada separada com nulo (Linux, * BSD), ou o próprio arquivo zsh %code% :

autoload -U zargs
zargs -r -e '' -- *(om) '' somecommand

Para processar um arquivo de cada vez, use um loop simples, que permite que você abrevie (csh-style):

for x (*(om)) somecommand
    
por 12.08.2014 / 02:22

Tags