¿Cómo puedo enumerar recursivamente todos los archivos que se cambiaron entre 22.12.2011 y 24.12.2011?
¿Cómo puedo enumerar recursivamente todos los archivos que se cambiaron entre 22.12.2011 y 24.12.2011?
Respuestas:
En términos generales, cuando busca archivos en un directorio y sus subdirectorios de forma recursiva, use find
.
La forma más fácil de especificar un rango de fechas find
es crear archivos en los límites del rango y usar el -newer
predicado.
touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop
-newer
se necesita negar la salida del primero aquí?
-newer
no se niega, el segundo sí. "Buscar archivos que son más nuevos start
pero no más nuevos que stop
".
start
y stop
.
Usando la solución de Gilles y después de leer man find (1) nuevamente, encontré una solución más simple. La mejor opción es -newerXY. Se pueden usar las banderas myt.
m The modification time of the file reference
t reference is interpreted directly as a time
Entonces la solución es
find . -type f -newermt 20111222 \! -newermt 20111225
El límite inferior en inclusivo, y el límite superior es exclusivo, ¡así que le agregué 1 día! Y es recursivo. Funciona bien en find v4.5.9.
find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l
( -m 50
= buscar en las primeras 50 líneas).
-exec ... +
en find(1)
, como: find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +
. Esto hace lo mismo, pero más barato.
find 4.7.0-git
).
Además de las respuestas ya dadas, tenga en cuenta que puede especificar directamente sus fechas:
find -type f -newermt "2011-12-22" \! -newermt "2011-12-24"
o
find -type f -newermt "2011-12-22 00:00:00" \! -newermt "2011-12-24 13:23:00"
si además desea especificar la hora.
Suponiendo que no necesita precisión en los segundos, esto debería funcionar.
find . -type f -mmin -$(((`date +%s`-`date -d 20111222 +"%s"`)/60)) \! -mmin +$(((`date +%s`-`date -d 20111224 +"%s"`)/60))
EDIT: Cambiado cmin
a mmin
después del comentario de @ Eelvex.
EDITAR: '\!' desaparecido
-cmin
es "cambio de estado", -mmin
es "cambio de datos". Probablemente quieras-mmin
find
puede tomar una fecha y hora con formato ISO, por lo que para un servidor en UTC, por ejemplo, puede especificar un desplazamiento de una cantidad de horas desde donde se encuentre. Esto también se ocupa de tener que agregar un día ya que también está comparando el tiempo:
find -type f -newermt 20111224T0800 \! -newermt 20111225T0800
Tenga en cuenta que la pregunta marcada como duplicada y, por lo tanto, no puede responderla directamente, es por eso que estoy publicando aquí. Esta respuesta es para responder la pregunta "necesita mover archivos a una carpeta diferente según la fecha de creación [duplicado]"
Las respuestas son razonables, pero hubo algunas limitaciones con un comando puramente de búsqueda. Escribí este script de shell para ir a través de un directorio con tantos archivos que el sistema de archivos tenía náuseas en los metadatos que intentaban realizar un ls. Además, algunos sistemas * nix rechazarán un error de demasiados argumentos al ejecutar ls.
El comando find es muy poderoso y comencé con los métodos enumerados, pero tenía tantos años de datos en todo ese directorio que tuve que pasar todos los archivos repetidamente. Esto produce una gran cantidad de innecesarios pasados sobre cada archivo. Intenté hacer una pantalla por año y ejecutar varios hallazgos, pero esto resultó en muchos errores de cada hallazgo y los archivos se perderían cuando uno de los hallazgos lo movió.
Mi script de shell mueve un archivo al directorio de destino, con un año de 4 dígitos y un mes de 2 dígitos. Se puede ampliar fácilmente a un día de 2 dígitos descomentando un par de líneas y comentando sus contrapartes. Creo que es más eficiente porque se realizaron los movimientos en una pasada de búsqueda, por lo que no se necesitan múltiples comandos de búsqueda y pases sobre el directorio.
#!/bin/bash
#We want to exit if there is no argument submitted
if [ -z "$1" ]
then
echo no input file
exit
fi
#destDir should be set to where ever you want the files to go
destDir="/home/user/destination"
#Get the month and year of modification time
#--format %y returns the modification date in the format:
# 2016-04-26 12:40:48.000000000 -0400
#We then take the first column, split by a white space with awk
date=`stat "$1" --format %y | awk '{ print $1 }'`
#This sets the year variable to the first column split on a - with awk
year=`echo $date | awk -F\- '{print $1 }'`
#This sets the month variable to the second column split on a - with awk
month=`echo $date | awk -F\- '{print $2 }'`
#This sets the day variable to the third column split on a - with awk
#This is commented out because I didn't want to add day to mine
#day=`echo $date | awk -F\- '{print $3 }'`
#Here we check if the destination directory with year and month exist
#If not then we want to create it with -p so the parent is created if
# it doesn't already exist
if [ ! -d $destDir/$year/$month ]
then
mkdir -p $destDir/$year/$month || exit
fi
#This is the same as above but utilizes the day subdirectory
#Uncommented this out and comment out the similar code above
#if [ ! -d $destDir/$year/$month/$day ]
#then
# mkdir -p $destDir/$year/$month$day || exit
#fi
#Echoing out what we're doing
#The uncommented is for just year/month and the commented line includes day
#Comment the first and uncomment the second if you need day
echo Moving $1 to $destDir/$year/$month
#echo Moving $1 to $destDir/$year/$month/$day
#Move the file to the newly created directory
#The uncommented is for just year/month and the commented line includes day
#Comment the first and uncomment the second if you need day
mv "$1" $destDir/$year/$month
#mv "$1" $destDir/$year/$month/$day
Una vez guardado y ejecutado, puede llamar a este script con find como el siguiente.
find /path/to/directory -type f -exec /home/username/move_files.sh {} \;
No necesita preocuparse por configurar la opción newermt para buscar, ya que todo lo que proporciona es una sola ejecución por archivo encontrado y el script toma todas las decisiones.
Tenga en cuenta que si no selecciona -type f, moverá los directorios y eso probablemente causará problemas. También puede usar -type d si está buscando mover solo directorios. No establecer el tipo seguramente producirá un comportamiento no deseado.
Recuerda que este guión se adaptó a mis necesidades. Es posible que desee utilizar simplemente mi construcción como inspiración para un guión más adecuado para sus necesidades. ¡Gracias!
Consideraciones: La eficiencia del comando puede mejorarse GRANDEMENTE permitiendo que pase un número ilimitado de argumentos a través del script. En realidad, esto es relativamente fácil si pasa la variable $ @. Ampliar la funcionalidad de esto nos permitiría usar la función find -exec + o aprovechar xargs, por ejemplo. Puedo implementarlo rápidamente y mejorar mi propia respuesta, pero este es un comienzo.
Dado que esta fue una sesión de script de una sola vez, probablemente hay muchas mejoras que se pueden hacer. ¡Buena suerte!