Você não precisa recorrer a comandos externos (como ls
) porque find
pode fazer tudo que precisa por meio da ação -printf
:
find /path -printf '%T+ %p\n' | sort -r | head
Se eu quiser encontrar o arquivo mais recente (mtime) em um diretório (grande) contendo subdiretórios, como eu o faria?
Várias postagens que eu encontrei sugerem alguma variação de ls -lt | head
(divertidamente, muitos sugerem ls -ltr | tail
, que é o mesmo, mas menos eficiente), o que é bom, a menos que você tenha subdiretórios (eu faço).
Então, novamente, você poderia
find . -type f -exec ls -lt \{\} \+ | head
que definitivamente fará o truque para quantos arquivos forem especificados por um comando, ou seja, se você tiver um diretório grande , -exec...\+
emitirá comandos separados; portanto, cada grupo será classificado por ls
dentro de si, mas não acima do conjunto total; a cabeça, portanto, pegará a última entrada do primeiro lote.
Alguma resposta?
Você não precisa recorrer a comandos externos (como ls
) porque find
pode fazer tudo que precisa por meio da ação -printf
:
find /path -printf '%T+ %p\n' | sort -r | head
Eu tive um problema semelhante hoje, mas o ataquei sem find
. Eu precisava de algo curto Eu poderia atropelar ssh
para retornar o arquivo editado mais recentemente no meu diretório home. Isso é basicamente o que eu criei:
ls -tp | grep -v /$ | head -1
A opção -p
para ls
adiciona uma barra à diretórios, o grep -v
remove as linhas que terminam em uma barra (aka, todos os diretórios) e o head -1
limita a saída a um único arquivo. / p>
Isso é muito menos detalhado do que usar find
se tudo que você deseja retornar é o nome do arquivo.
Isso está no meu sistema mais rápido que printf
, embora eu não entenda por que
find /path -type f -exec stat -c "%y %n" {} + | sort -r | head
Não é quase tão na moda, mas também é possível conseguir isso com o Midnight Commander : procure por *, panelize o resultado, classifique por tempo de modificação na ordem inversa.
Obviamente, é um pouco mais lento que find
- meu diretório inicial, contendo 922000 arquivos, foi classificado por mc
em quase 14 minutos enquanto find
gastou menos de 5 - mas há alguns benefícios:
Eu provavelmente gastaria mais do que a diferença de 9 minutos inventando uma invocação de busca adequada:)
menos chance de erro (esqueci de especificar -r para ordenar etc. - começar de novo)
é possível jogar com o conjunto de resultados alterando a ordem de classificação, etc. - sem reexaminar os arquivos.
possível executar operações de arquivo apenas em alguns arquivos do conjunto de resultados - ou seja, classificar por tamanho, excluir alguns arquivos grandes que não são necessários
EDIT: Eu acho que este post não é "não particularmente útil", como eu pensava que era. Esta é uma solução muito rápida que apenas acompanha o arquivo modificado mais recentemente (em vez de classificar toda a lista de arquivos):
find . -type f -printf '%T@ %p\n' | awk 'BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; } { if ($1 > mostrecenttime) { mostrecenttime = $1; mostrecentline = $0; } } END { print mostrecentline; }' | cut -f2- -d ' '
Espalhe várias linhas para maior clareza:
find . -type f -printf '%T@ %p\n' | awk '
BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; }
{
if ($1 > mostrecenttime)
{ mostrecenttime = $1; mostrecentline = $0; }
}
END { print mostrecentline; }' | cut -f2- -d ' '
Fim do EDIT
Não é um post particularmente útil, mas como 'organize' estava discutindo a velocidade, pensei em compartilhar isso.
As soluções do array e da enzotib envolvem a listagem de todos os arquivos dentro do diretório com seus mtimes e, em seguida, a classificação. Como você sabe, a classificação não é necessária para encontrar o máximo. Encontrar o máximo pode ser feito em tempo linear, mas a ordenação leva n log (n) tempo [Eu sei que a diferença não é muito, mas ainda;)]. Não consigo pensar em uma maneira legal de implementar isso. [EDIT: Uma implementação simples (embora de aparência suja) e rápida fornecida acima.]
Próxima melhor coisa - Para encontrar o arquivo editado mais recentemente em um diretório, localize recursivamente o arquivo editado mais recentemente em cada subdiretório de nível 1. Deixe este arquivo representar o subdiretório. Agora, classifique os arquivos de nível 1 junto com os representantes dos subdiretórios de nível 1. Se o número do número de arquivos e subdiretórios de nível 1 de cada diretório for quase uma constante, esse processo deverá ser dimensionado linearmente com o número total de arquivos.
Isso é o que eu criei para implementar isso:
findrecent() { { find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1; }
findrecent .
Eu corri isso e recebi um monte de erros find: findrecent: No such file or directory
. Razão: -exec de find é executado em um shell diferente. Eu tentei definir findrecent em .bashrc, .xsessionrc mas estes não ajudaram [eu apreciaria a ajuda aqui]. No final, eu recorri a colocar
#!/bin/bash
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;
em um script chamado findrecent
no meu PATH e depois executá-lo.
Eu corri isso, fiquei esperando e esperando sem saída. Só para ter certeza de que não estava lidando com nenhum loop infinito, modifiquei o arquivo para
#!/bin/bash
echo "$1" >&2
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;
e tentei novamente. Ele funcionou - mas demorou 1 minuto e 35 segundos em minha casa - as soluções do arranjo e da enzotib levaram 1,69, 1,95 segundo, respectivamente!
Tanto para a superioridade de O (n) sobre O (n log (n))! Porra você chama a função de sobrecarga! [Ou melhor, sobrecarga de chamada de script]
Mas esse script é dimensionado melhor que as soluções anteriores e aposto que ele será executado com mais rapidez do que no banco de memória do Google; D
Use perl
no conjonctin com find
:
find my_directory -type f -printf '%T@\t%p\n' | perl -ane '@m=@F if ($F[0]>$m[0]); END{print $m[1];}'
Você obtém o nome do arquivo com o maior epoch == último arquivo modificado.
Tags command-line find