¿Cómo enumerar archivos anteriores a un día con "2015" en el nombre del archivo?

11

Quiero enumerar todos los archivos de registro que no pertenecen hoy y solo los archivos que contienen 2015en sus nombres.

Estos son los comandos que he probado:

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

La salida de ambos no es nada, pero aún así, los archivos están ahí. Algo está mal con estos comandos, y no entiendo qué. Cualquier ayuda sería apreciada.

rɑːdʒɑ
fuente
La findparte me parece bien, pero también tuve problemas con el -execparámetro. No pude hacer que eso funcione tampoco. (Estaba tratando de mover todos los archivos jpg de una carpeta a su directorio principal a través de él, y terminé haciéndolo manualmente ...)
Byte Commander
2
Es posible que desee echar un vistazo a ¿Por qué find -mtime +1 solo devuelve archivos anteriores a 2 días?
steeldriver
@steeldriver Creo que eso es realmente lo que está sucediendo aquí, ya que si hubiera archivos en el directorio actual con 2015su nombre (la otra deficiencia obvia de la forma en que se escribe el comando) sospecho que habría algún tipo de salida. Por lo tanto, es posible que desee publicar una respuesta al respecto.
Eliah Kagan

Respuestas:

18

El comando find . -name '*2015*' -mmin +1440 -lsprobablemente hará lo que quieras. Ver abajo para más detalles.

Tu primer comando tenía -name 2015. No funcionó porque encuentra solamente archivos cuyos nombres son exactamente 2015 , sin otros personajes en ellos.

Su segundo comando, find . -name *2015* -mtime +1 -exec ls -ltrh {} \;podría haber fallado por un par de razones:

1. El shell expande los *caracteres sin comillas y luego los pasa a find.

Si hay archivos directamente contenidos en el directorio actual (en el que estaba cuando ejecutó ese find ...comando) cuyos nombres contienen 2015(y no comienzan con a .), el shell se expandió *2015*en una lista de esos nombres de archivo, luego pasó esa lista como argumentos para find. Esto no es lo que desea, en su lugar, desea pasar *2015*literalmente como un argumento para encontrar, de modo que find, y no el shell, pueda encontrar qué archivos coinciden.

Para solucionar ese problema, cita *2015*. Hay tres formas comunes de hacerlo:

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

Yo sugiero escribirlo entre comillas simples como '*2015*', debido a que:

Pero en este caso realmente no importa. 'y "ambos tratan *lo mismo y la expresión no es lo suficientemente complicada como para \citarla y dificultar su comprensión.

2. -mtime +1solo selecciona archivos modificados hace dos o más días.

Como man finddice:

       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.

Supongamos que un archivo se modificó hace 47 horas. Para calcular cuántos períodos de 24 horas son, findredondee hacia abajo : es un período de 24 horas atrás. Pero -mtime +1solo coincide con archivos cuyos tiempos de modificación son estrictamente más de un período de 24 horas atrás. Por lo tanto, los archivos de ayer no coinciden.

Consulte ¿Por qué find -mtime +1 solo devuelve archivos anteriores a 2 días? para más información, como lo sugiere steeldriver .

Para buscar archivos modificados por última vez en cualquier momento hace más de 24 horas , sugiero que lo estipule como hace 1440 minutos con -mmin +1440:

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

Algunos lectores podrían preguntarse por qué no cité {}. Algunas personas citan {}para recordar a los humanos que no es una expresión para la expansión de aparatos ortopédicos . Las conchas de estilo Bourne (como bash ) no requieren {}que se cite nada dentro. Quizás algún shell que no sea de Bourne lo trate especialmente; Esa podría ser la razón por la que algunos usuarios lo citan. Pero también hay una idea errónea de que a veces uno debe citar, {}por lo que -execmaneja los nombres de archivos con espacios correctamente. Eso es falso: con {}o '{}', findobtiene los mismos argumentos, ya que el shell elimina las comillas antes de pasar '{}'afind. Para contrarrestar esta idea errónea, no cito {}, pero es una cuestión de estilo: si prefiere {}documentar cómo no se trata el shell {y }, especialmente, está bien.

Le recomiendo que también cambie su lscomando o (como ha sugerido muru ) lo reemplace con findla -lsacción. ls -ltrhprobablemente no está haciendo lo que pretendes porque se ejecuta por separado para cada archivo encontrado y, por lo tanto, los indicadores -ty -r, que especifican la clasificación, son irrelevantes.

Aunque la salida tendrá un formato un poco diferente que con ls -l, el uso -lses más simple y fácil.

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

O si decide que realmente solo necesita enumerar los nombres del archivo (incluidas sus rutas, en relación con .), simplemente puede especificar ninguna acción, lo que hace -printque se use la acción predeterminada :

find . -name '*2015*' -mmin +1440
Eliah Kagan
fuente
1
Buena respuesta completa! al menos con GNU find, también existe la newerXYsintaxis, que acepta argumentos de calendario, por ejemplo, -newermt 'yesterday'y! -newermt 'yesterday'
steeldriver
Sabes que ? Eres increíble. @ Eliah Kagan
rɑːdʒɑ
Gracias Stell Driver, esa es muy buena información del enlace para saber. Pero en mi caso, como lo es el registro de la aplicación, los archivos antiguos de la aplicación no tienen forma de modificarse. Gracias de nuevo
rɑːdʒɑ
2

Cita la expresión y te sugiero que también comas los corchetes

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

o

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

no necesita pasar los archivos que encuentre a ls

find . -name "*2015*" -mtime +1
Pantera
fuente
Tal vez restringir el uso -type f? Y si lstiene que ser usado, sugiera usarlo -ls.
muru
1
Claro, todas buenas sugerencias. No estoy seguro de lo que quiere el OP y creo que la fuente del problema es la falta de comillas alrededor del patrón de búsqueda "-name".
Panther
2

En zsh , puede usar calificadores glob (esta es una característica única de zsh, no disponible en otros shells como bash).

ls -ltr *2015*(m+1)

Esto solo enumera los archivos en el directorio actual; para recorrer directorios recursivamente , use

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

Con find, -name 2015solo encuentra archivos cuyo nombre es exactamente 2015. -name *2015*solo funciona si no hay archivos cuyo nombre contenga 2015en el directorio actual, porque el shell expande el patrón *2015*antes de que findse invoque. Necesita citar el patrón:

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

Tenga en cuenta que ambos find -mtime +1y zsh *(m+1)encuentran archivos que tienen al menos 48 horas de antigüedad , no archivos más antiguos que hoy. El signo más significa "estrictamente más que" y el número de días se redondea hacia abajo. Para buscar archivos que tengan al menos 24 horas de antigüedad, use -mtime +0o (m+0).

Si desea buscar archivos que se modificaron por última vez ayer o antes , puede usar findel -newermtpredicado :

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

No hay una forma realmente conveniente de hacer esta prueba en zsh.

Gilles 'SO- deja de ser malvado'
fuente