Como listar arquivos com mais de um dia com "2015" no nome do arquivo?

11

Quero listar todos os arquivos de log que não pertencem hoje e apenas os arquivos que contêm 2015seus nomes.

Estes são os comandos que eu tentei:

find . -name 2015 -mtime +1 -exec  ls -ltrh  {} \;
find . -name *2015* -mtime +1 -exec  ls -ltrh  {} \;

A saída de ambos não é nada, mas ainda existem arquivos. Algo está errado com esses comandos, e eu não estou entendendo o quê. Qualquer ajuda seria apreciada.

rɑːdʒɑ
fonte
A findparte parece boa para mim, mas também tive problemas com o -execparâmetro. Também não consegui fazer isso funcionar. (Eu estava tentando mover todos os arquivos JPG de uma pasta para seu diretório pai por ele - e acabou por fazê-lo manualmente ...)
Byte Comandante
@steeldriver Eu acho que é realmente isso que está errado aqui, pois se houvesse arquivos no diretório atual com 2015o nome deles (a outra falha óbvia na maneira como o comando é escrito), suspeito que haveria algum tipo de saída. Então, você pode postar uma resposta sobre isso.
Elias Kagan

Respostas:

18

O comando find . -name '*2015*' -mmin +1440 -lsprovavelmente fará o que você deseja. Veja abaixo para detalhes.

Seu primeiro comando teve -name 2015. Não funcionou porque encontra apenas arquivos cujos nomes são exatamente 2015 , sem outros caracteres.

Seu segundo comando,, find . -name *2015* -mtime +1 -exec ls -ltrh {} \;pode ter falhado por alguns motivos:

1.* Caracteres não citados são expandidos pelo shell e depois transmitidos para find.

Se houver algum arquivo diretamente contido no diretório atual (aquele em que você executou esse find ...comando) cujos nomes contenham 2015(e não inicie com a .), o shell se expandiu *2015*para uma lista desses nomes de arquivos e passou essa lista como argumentos para find. Não é isso que você deseja - em vez disso, você deseja passar *2015*literalmente como um argumento a ser encontrado, para que find, e não o shell, encontre quais arquivos correspondem a ele.

Para corrigir esse problema, cite *2015*. Existem três maneiras comuns de fazer isso:

  • '*2015*'(ie find . -name '*2015*' -mtime +1 -exec ls -ltrh {} \;)
  • "*2015*"(ie find . -name "*2015*" -mtime +1 -exec ls -ltrh {} \;)
  • \*2015\*(ie find . -name \*2015\* -mtime +1 -exec ls -ltrh {} \;)

Eu sugiro escrevê-lo com aspas simples como '*2015*', porque:

Mas, neste caso, isso realmente não importa. 'e "ambos tratam *o mesmo e a expressão não é complicada o suficiente para \citar para dificultar a compreensão.

2. -mtime +1seleciona apenas arquivos modificados há dois ou mais dias.

Como man finddiz:

       Numeric arguments can be specified as

       +n     for greater than n,

       -n     for less than n,

       n      for exactly n.
       -mtime n
              File's data was last modified n*24 hours ago.  See the  comments
              for -atime to understand how rounding affects the interpretation
              of file modification times.
       -atime n
              File was last accessed n*24 hours ago.  When  find  figures  out
              how  many  24-hour  periods  ago the file was last accessed, any
              fractional part is ignored, so to match -atime +1, a file has to
              have been accessed at least two days ago.

Suponha que um arquivo foi modificado 47 horas atrás. Para descobrir quantos períodos de 24 horas são findarredondados para baixo : é um período de 24 horas atrás. Mas -mtime +1corresponde apenas a arquivos cujos horários de modificação são estritamente mais de um período de 24 horas atrás. Assim, os arquivos de ontem não são correspondidos.

Consulte Por que encontrar -mtime +1 retorna apenas arquivos com mais de 2 dias? para obter mais informações, conforme sugerido pela steeldriver .

Para encontrar os arquivos modificados pela última vez a qualquer hora, mais de 24 horas atrás , sugiro estipulá-lo como 1440 minutos atrás com -mmin +1440:

find . -name '*2015*' -mmin +1440 -exec ls -ltrh {} \;

Alguns leitores podem estar se perguntando por que não citei {}. Algumas pessoas citam {}para lembrar aos seres humanos que não é uma expressão para a expansão da cinta . As conchas no estilo Bourne (como o bash ) não exigem {}nada dentro para serem citadas. Talvez algum shell que não seja do estilo Bourne o trate especialmente; pode ser por isso que alguns usuários o citam. Mas há também um equívoco que às vezes é necessário citar, {}para que os -execnomes de arquivos sejam tratados com espaços corretamente. Falsa s; que: com {}ou '{}', findrecebe os mesmos argumentos, como o shell remove as aspas antes de passar '{}'parafind. Para combater esse equívoco, não cito {}, mas é uma questão de estilo - se você preferir {}documentar como o shell não está tratando {e }, especialmente, tudo bem.

Eu recomendo que você também quer mudar o seu lscomando, ou (como Muru sugeriu ) substituí-la por find's -lsação. ls -ltrhprovavelmente não está fazendo o que você pretende, porque é executado separadamente para cada arquivo encontrado e, portanto, os sinalizadores -te -r, que especificam a classificação, são irrelevantes.

Embora a saída seja formatada um pouco diferente do que com ls -l, o uso -lsé mais simples e fácil.

find . -name '*2015*' -mmin +1440 -ls

Ou, se você decidir que realmente precisa apenas listar os nomes dos arquivos (incluindo seus caminhos, em relação a .), basta especificar nenhuma ação, fazendo com que a -printação padrão seja usada:

find . -name '*2015*' -mmin +1440
Eliah Kagan
fonte
1
Boa resposta completa! pelo menos com GNU achado, há também a newerXYsintaxe, que aceita argumentos de calendário, por exemplo, -newermt 'yesterday'e! -newermt 'yesterday'
steeldriver
Você sabe o que ? @ Eliah Kagan
rɑːdʒɑ
Obrigado, driver stell, é uma informação muito boa do link para saber. Mas no meu caso, como é o log do aplicativo, os arquivos antigos do aplicativo não têm como ser modificados. Obrigado novamente
r --dɑː
2

Cite a expressão e sugiro que você cite os colchetes também

find . -name "2015" -mtime +1 -exec  ls -ltrh  '{}' \;

ou

find . -name "*2015*" -mtime +1 -exec  ls -ltrh  '{}' \;

você não precisa passar os arquivos encontrados para ls

find . -name "*2015*" -mtime +1
Pantera
fonte
Talvez restringir o uso -type f? E se lstiver que ser usado, sugira usar -ls.
Muru
1
com certeza, todas as boas sugestões. Não tenho certeza do que o OP deseja e acredito que a fonte do problema seja a falta de aspas no padrão de pesquisa "-name".
Pantera
2

No zsh , você pode usar qualificadores glob (esse é um recurso exclusivo do zsh, não disponível em outros shells, como o bash).

ls -ltr *2015*(m+1)

Isso lista apenas os arquivos no diretório atual; para percorrer diretórios recursivamente , use

ls -ltr **/*2015*(m+1)

Com find, -name 2015localiza apenas arquivos cujo nome é exatamente 2015. -name *2015*só funciona se não houver arquivos cujo nome contenha 2015no diretório atual, porque o shell expande o padrão *2015*antes de findser chamado. Você precisa citar o padrão:

find -name '*2015*' -mtime +1 …

Observe que ambos find -mtime +1e o zsh *(m+1)encontram arquivos com pelo menos 48 horas de duração , e não arquivos mais antigos que hoje. O sinal de mais significa "estritamente mais que" e o número de dias é arredondado para baixo. Para encontrar arquivos com pelo menos 24 horas de duração, use -mtime +0ou (m+0).

Se você deseja encontrar arquivos que foram modificados pela última vez ontem ou antes , você pode usar findcom o -newermtpredicado :

find -name '*2015*' ! -newermt 'today 0:00' …

Não existe uma maneira realmente conveniente de fazer esse teste no zsh.

Gilles 'SO- parar de ser mau'
fonte