Comment répertorier de manière récursive tous les fichiers modifiés entre le 22.12.2011 et le 24.12.2011?
Comment répertorier de manière récursive tous les fichiers modifiés entre le 22.12.2011 et le 24.12.2011?
Réponses:
En règle générale, lorsque vous recherchez des fichiers dans un répertoire et ses sous-répertoires de manière récursive, utilisez find
.
Le moyen le plus simple de spécifier une plage de dates find
consiste à créer des fichiers aux limites de la plage et à utiliser le -newer
prédicat.
touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop
-newer
est nécessaire ici?
-newer
n'est pas nié, le second l'est. "Rechercher des fichiers plus récents que start
mais pas plus récents que stop
".
start
et stop
.
En utilisant la solution de Gilles et après avoir lu l' homme à trouver (1) , j'ai trouvé une solution plus simple. La meilleure option est le -newerXY. Les drapeaux m et t peuvent être utilisés.
m The modification time of the file reference
t reference is interpreted directly as a time
Donc la solution est
find . -type f -newermt 20111222 \! -newermt 20111225
La limite inférieure en inclusif et la limite supérieure sont exclusives, alors j’y ai ajouté 1 jour! Et c'est récursif. Cela fonctionne bien sur find v4.5.9.
find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l
( -m 50
= recherche dans les 50 premières lignes).
-exec ... +
dans find(1)
, comme: find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +
. Cela fait la même chose, mais moins cher.
find 4.7.0-git
).
En supposant que vous n’ayez pas besoin de précision aux secondes, cela devrait fonctionner.
find . -type f -mmin -$(((`date +%s`-`date -d 20111222 +"%s"`)/60)) \! -mmin +$(((`date +%s`-`date -d 20111224 +"%s"`)/60))
EDIT: Changé cmin
pour mmin
après @ commentaire de Eelvex.
EDIT: '\!' manquant
-cmin
est "changement d'état", -mmin
est "changement de données". Vous voulez probablement-mmin
find
peut prendre une date / heure au format ISO. Ainsi, pour un serveur au format UTC, par exemple, vous pouvez spécifier un décalage d’un nombre d’heures peu importe où vous vous trouvez. Cela évite également d’ajouter un jour puisque vous comparez aussi le temps:
find -type f -newermt 20111224T0800 \! -newermt 20111225T0800
Veuillez noter que la question marquée comme étant en double et, par conséquent, empêchée d'y répondre directement, est la raison pour laquelle je poste ici. Cette réponse sert à répondre à la question "Nécessité de déplacer des fichiers vers un dossier différent en fonction de la date de création [dupliquer]"
Les réponses sont raisonnables mais il y avait quelques limitations avec une commande purement trouver. J'ai écrit ce script shell pour parcourir un répertoire contenant autant de fichiers que le système de fichiers bâillonnait sur les métadonnées en essayant d'exécuter un ls. De plus, certains systèmes * nix verront une erreur de nombre d'arguments trop importante avec ls.
La commande find est très puissante et j'ai commencé avec les méthodes répertoriées, mais j'avais des années de données dans ce répertoire et je devais passer tous les fichiers à plusieurs reprises. Cela produit beaucoup de données inutiles sur chaque fichier. J'ai essayé de faire un écran par an et d'exécuter plusieurs recherches, mais cela a entraîné beaucoup d'erreurs dans chaque recherche et des fichiers disparaissaient lorsque l'une des recherches le déplaçait.
Mon script shell déplace un fichier dans le répertoire de destination, avec une année à 4 chiffres et un mois à 2 chiffres. Il peut facilement être étendu à un jour à 2 chiffres en décommentant quelques lignes et en commentant leurs homologues. Je crois que c’est plus efficace parce que c’est-à-dire qu’il fallait effectuer les déplacements en un seul passage, de sorte que plusieurs commandes de recherche et passages sur le répertoire sont inutiles.
#!/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
Une fois enregistré et rendu exécutable, vous pouvez appeler ce script avec find comme suit.
find /path/to/directory -type f -exec /home/username/move_files.sh {} \;
Vous n'avez pas besoin de vous inquiéter de la définition de l'option newermt pour find car tout ce que find fournit est une seule exécution par fichier trouvé et le script prend toutes les décisions.
Gardez à l'esprit que si vous ne sélectionnez pas -type f, les répertoires seront déplacés, ce qui causera probablement des problèmes. Vous pouvez également utiliser -type d si vous souhaitez déplacer uniquement des répertoires. Ne pas définir le type provoquera presque certainement un comportement indésirable.
Rappelez-vous que ce script a été adapté à mes besoins. Vous voudrez peut-être simplement utiliser ma construction comme source d'inspiration pour un script mieux adapté à vos besoins. Merci!
Considérations: L’efficacité de la commande peut être grandement améliorée en permettant à un nombre illimité d’arguments de passer à travers le script. C'est en fait relativement facile si vous passez sur la variable $ @. En étendant les fonctionnalités, nous pourrions utiliser la fonction -exec + de find ou tirer parti de xargs, par exemple. Je peux rapidement mettre en œuvre cela et améliorer ma propre réponse, mais c'est un début.
Comme il s’agissait d’une session de script unique, de nombreuses améliorations peuvent probablement être apportées. Bonne chance!