Achatar a saída de uma listagem de diretórios recursivos

7

Existe uma maneira de listar todos os arquivos dentro de um diretório árvore em uma única lista, classificada por hora de modificação no Linux?

ls -Rlt 

lista os arquivos recursivamente, mas eles são agrupados em pastas diferentes na saída e, como resultado, a saída não é classificada como um todo. Apenas o conteúdo de cada diretório é classificado por hora.

    
por mahela007 25.12.2015 / 14:58

3 respostas

11

Sim, você pode fazer isso com o GNU find . Se os nomes dos seus arquivos não contiverem novas linhas, você pode fazer:

find -printf '%T@ %p\n' | sort -gk1,1

Explicação

  • A opção -printf de find pode imprimir todos os tipos de informações. Neste caso, estamos usando:

    %Tk    File's last modification time in the format specified  by
           k, which is the same as for %A.
    @      seconds  since Jan. 1, 1970, 00:00 GMT, with fractional part.
    %p     File's name.
    

    Portanto, %T@ %p\n imprimirá o tempo de modificação do arquivo em segundos desde a época ( %T@ ), um espaço e, em seguida, o nome do arquivo ( %p ).

  • Estes são então passados para sort , que é ordenado a ordenar numericamente ( -n ) apenas no primeiro campo ( -k1,1 ).

Observe que isso retornará todos os arquivos e diretórios. Para restringi-lo apenas a arquivos regulares (sem diretórios, arquivos de dispositivos, links, etc.), adicione -type f ao seu comando find .

Para obter datas legíveis, você pode processar a saída com o GNU date :

find -printf '%T@ %p\t\n' | sort -gk1,1 | 
    perl -lne 's/([^ ]*)//;chomp($i='date -d \@$1'); print "$i $_"'

Aqui, o comando perl substitui a primeira cadeia de caracteres não espaciais (a data) por si própria, conforme processada pelo GNU date .

Os itens acima falharão para nomes de arquivos que contenham novas linhas. Para lidar com novas linhas, use:

find -printf '%p\t%T@
find -printf '%T@ %p\n' | sort -gk1,1
' | sort -zt$'\t' -nk2 | tr '
%Tk    File's last modification time in the format specified  by
       k, which is the same as for %A.
@      seconds  since Jan. 1, 1970, 00:00 GMT, with fractional part.
%p     File's name.
' '\n'

Essa é a mesma coisa, exceto que find produzirá um \n em vez de sort no final de cada nome de arquivo. O GNU tr pode lidar com a saída separada por nulo, portanto, ainda é capaz de classificar corretamente. O comando final \n traduz o %code% de volta para %code% .

    
por 25.12.2015 / 15:32
5

com zsh :

print -rl -- **/*(D.om)

** / * corresponde a qualquer nível de subdiretórios (e não segue a links simbólicos). D. qualificadores listam arquivos regulares, om classifica-os por hora de modificação, o mais novo primeiro.

Se você deseja que os nomes dos arquivos sejam listados sem a parte do diretório, adicione o modificador t history:

print -rl -- **/*(D.om:t)
    
por 25.12.2015 / 16:11
0

bem, se você está falando sobre muitos milhares de arquivos - e tão além do seu ARG_MAX limit - então ele não sairá tão bem, mas a solução mais simples é:

find . ! -type d -exec ls -t {} +

... que chamará ls para cada lote de <=ARG_MAX arquivos que puder encontrar. Também não há restrições arbitrárias nos caracteres nos nomes de caminho, apenas no número máximo de argumentos que podem ser processados juntos.

Ele gravará a saída de forma idêntica à saída de find . Você pode usar qualquer outra opção, como -l ou -h do GNU. Aqui estão alguns listados de uma pequena árvore que criei há uma semana:

find . ! -type d -exec ls -lht {} +
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir/dir1/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir/dir2/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir/dir3/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir2/dir1/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir2/dir2/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 19:00 ./dir2/dir3/file
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir/file1
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir/file2
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir/file3
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir2/file1
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir2/file2
-rw-r--r-- 1 mikeserv mikeserv   0 Dec 19 18:57 ./dir2/file3

... que obviamente não estão agrupados por diretório.

Na minha máquina ...

getconf ARG_MAX
2091752

... mas não acho que seja realista. Eu acho que é algo como mais ou menos 65k em média.

    
por 26.12.2015 / 06:38