Se eu quiser encontrar o arquivo mais recente (mtime) em um diretório (grande) contendo subdiretórios, como eu faria isso?
Muitas postagens que encontrei sugerem alguma variação ls -lt | head
(divertidamente, muitas sugerem ls -ltr | tail
que é a mesma, mas menos eficiente), o que é bom, a menos que você tenha subdiretórios (eu tenho).
Então, novamente, você poderia
find . -type f -exec ls -lt \{\} \+ | head
o que definitivamente fará o truque para quantos arquivos puderem ser especificados por um comando, ou seja, se você tiver um diretório grande , -exec...\+
emitirá comandos separados; portanto, cada grupo será classificado ls
dentro de si, mas não no conjunto total; portanto, o cabeçote coletará a última entrada do primeiro lote.
Alguma resposta?
command-line
find
Rico
fonte
fonte
find: missing argument to '-exec'
+
não tem significado parabash
, então não há necessidade de escapar dele.Respostas:
Você não precisa recorrer a comandos externos (as
ls
) porquefind
pode fazer tudo o que precisa através da-printf
ação:fonte
find . -type f -exec stat --format=%y \{\} \+ | sort -r | head -n1
mas sua solução é muito mais limpa!| cut -d ' ' -f2
para obter apenas o nome do arquivohead
para incluir um certo número de linhas. Eu só precisava da primeira linha, então useihead -n 1
Eu tive um problema semelhante hoje, mas o ataquei sem
find
. Eu precisava de algo curto parassh
poder retornar o arquivo editado mais recentemente no meu diretório pessoal. Isto é aproximadamente o que eu vim com:A
-p
opção dels
adicionar uma barra final aos diretórios,grep -v
remove as linhas que terminam em uma barra (também conhecida como todos os diretórios) ehead -1
limita a saída a um único arquivo.Isso é muito menos detalhado do que usar
find
se tudo o que você deseja retornar é o nome do arquivo.fonte
Isso está no meu sistema mais rápido que
printf
, embora eu não entenda por quefonte
... | sort -r | head -n1 | cut -d " " -f 4-
se você deseja obter apenas o nome do arquivo.sort -r
errado se o nome do arquivo em várias linhas existir.Edição: Eu acho que este post não é 'particularmente útil' como eu pensava que era. Esta é uma solução realmente rápida que apenas rastreia o arquivo modificado mais recentemente (em vez de classificar a lista inteira 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 por várias linhas para maior clareza:
Fim da edição
Não é um post particularmente útil, mas como 'organizar' estava discutindo velocidade, pensei em compartilhar isso.
As soluções de arranjo e enzotib envolvem a listagem de todos os arquivos dentro do diretório com seus respectivos tempos e 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 classificação leva n log (n) tempo [eu sei que a diferença não é muito, mas ainda assim;)]. Não consigo pensar em uma maneira elegante de implementar isso. [EDIT: Uma implementação limpa (embora com aparência desagradável) 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, juntamente com os representantes dos subdiretórios de nível 1. Se o número de arquivos de nível 1 e subdiretórios de cada diretório for quase constante, esse processo deverá ser dimensionado linearmente com o número total de arquivos.
Isto é o que eu vim para implementar isso:
Corri isso e recebi um monte de
find: findrecent: No such file or directory
erros. 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 colocarem um script chamado
findrecent
no meu PATH e depois executá-lo.Eu executei isso, continuei esperando e sem saída. Só para ter certeza de que não estava lidando com nenhum loop infinito, modifiquei o arquivo para
e tentei novamente. Funcionou - mas demorou 1 minuto e 35 segundos na minha pasta - as soluções do arranjo e do enzotib levaram 1,69, 1,95 segundos, respectivamente!
Tanto pela superioridade de O (n) sobre O (n log (n))! Droga, você trabalha com a chamada em cima! [Ou melhor, sobrecarga de chamada de script]
Mas esse script é melhor que as soluções anteriores e aposto que ele será executado mais rapidamente do que eles no banco de memória do Google; D
fonte
Use
perl
em conjunto comfind
:Você obtém o nome do arquivo com a maior época == último arquivo modificado.
fonte
Não está tão na moda, mas também é possível conseguir isso com o Midnight Commander : pesquise *, organize o resultado, classifique por tempo de modificação na ordem inversa.
Obviamente, é um pouco mais lento que
find
- meu diretório pessoal, contendo 922000 arquivos, foi classificadomc
em quase 14 minutos enquantofind
gasto menos de 5 - mas há alguns benefícios:Eu provavelmente gastaria mais tempo do que a diferença de 9 minutos inventando uma chamada de localização adequada :)
menor chance de erro (esqueceu de especificar -r para classificação etc. - comece novamente)
é possível jogar com o conjunto de resultados alterando a ordem de classificação etc. - sem consultar novamente 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
fonte