Localiza arquivos na ordem de data e hora

4

dir tem dois arquivos regulares.

file1 tem abc\n , file2 tem def\n . Comprima esses dois arquivos com gzip, como mostrado abaixo,

#ls
#echo 'abc\n' > file1
#echo 'def\n' > file2
#gzip file1
#gzip file2
#ls
file1.gz  file2.gz

Depois de catar o conteúdo,

#find . -type f  -name "*.gz" -exec zgrep -Iq . \{} \; -exec zcat \{} \;
def\n
abc\n

Eu não obtenho o conteúdo dos arquivos na ordem do tempo de criação do arquivo. A saída esperada deve ser sempre abc\ndef\n .

Observação interessante: a produção real é em algum momento, def\nabc\n e às vezes abc\ndef\n

Pergunta:

Como encontrar arquivos em ordem (diminuindo / aumentando) de timestamp?

    
por overexchange 30.05.2017 / 02:39

3 respostas

3

A ordem dos arquivos informados por find é opaca para o usuário. Pode ser a ordem em que aparecem no diretório. Algumas implementações de find as reordenam por número de inode ou outros critérios em uma tentativa de melhorar o desempenho. A única maneira pela qual alguém pode alterar a ordem é através do predicado -depth , que informa o find para o processo / saída antes do ramo em que estão.

Como uma alternativa para find , você pode usar o recurso glob recursivo de zsh :

zgrep whatever ./**/*.gz(D.Om)

O qualificador Om glob é classificar pelo horário da última modificação (o mais antigo primeiro). . é apenas para arquivos regulares (equivalente a find ' -type f ), D deve incluir itens ocultos (ponto) como find por padrão.

Se você obtiver um erro lista de args por muito tempo , poderá usar zargs :

autoload -U zargs # best in ~/.zshrc
zargs ./**/*.gz(D.Om) -- zgrep whatever

Com bash (ou qualquer shell suportando substituição de processos no estilo Ksh) e ferramentas GNU recentes, um equivalente seria:

xargs -r0a <(
  export LC_ALL=C
  find . -type f -name '*.gz' -printf '%T@\t%p
zgrep whatever ./**/*.gz(D.Om)
' | sort -zn | cut -zf2-) zgrep whatever
    
por 30.05.2017 / 13:22
1

Infelizmente, o comando find funciona de tal forma que a saída não é garantida como ordem alfabética ou de tempo de arquivo. Você pode tentar algo como:

ls -1dtr $(find . -maxdepth 1 -type f -name '*.gz') | xargs gzcat $1

Espero que isso ajude.

    
por 30.05.2017 / 04:47
1

Uma opção é exibir o registro de data e hora do arquivo junto com o caminho do arquivo, classificar por ele e, em seguida, removê-lo:

find -type f -name "*.gz" -printf '%C@\t%p\n'|sort -nk1|cut -f2-|xargs zcat 

Observe que, se seus nomes de arquivos puderem conter caracteres potencialmente inseguros (como espaços), basta substituir

xargs zcat 

com

xargs -d "\n" zcat 

e se você precisar acomodar as novas linhas nos nomes de arquivos, você pode usar um byte nulo para terminar os registros, conforme detalhado na resposta @ stéphane-chazelas (através disso, raramente é um problema na prática).

    
por 30.05.2017 / 13:10