Wie kann ich alle Dateien, die zwischen dem 22.12.2011 und dem 24.12.2011 geändert wurden, rekursiv auflisten?
Wie kann ich alle Dateien, die zwischen dem 22.12.2011 und dem 24.12.2011 geändert wurden, rekursiv auflisten?
Antworten:
Wenn Sie Dateien in einem Verzeichnis und seinen Unterverzeichnissen rekursiv suchen, verwenden Sie im Allgemeinen find
.
Die einfachste Möglichkeit, einen Datumsbereich anzugeben, find
besteht darin, Dateien an den Bereichsgrenzen zu erstellen und das -newer
Prädikat zu verwenden.
touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop
-newer
werden?
-newer
wird nicht negiert, der zweite ist. "Dateien suchen, die neuer als, start
aber nicht neuer als sind stop
".
start
und sind stop
.
Unter Verwendung von Gilles 'Lösung und nachdem ich den man find (1) wieder gelesen hatte, fand ich eine einfachere Lösung. Die beste Option ist -newerXY. Die Flags m und t können verwendet werden.
m The modification time of the file reference
t reference is interpreted directly as a time
Die Lösung ist also
find . -type f -newermt 20111222 \! -newermt 20111225
Die Untergrenze inklusiv und die Obergrenze ist exklusiv, also habe ich 1 Tag hinzugefügt! Und es ist rekursiv. Es funktioniert gut mit find v4.5.9.
find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l
( -m 50
= Suche in den ersten 50 Zeilen).
-exec ... +
in find(1)
, wie: find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +
. Dies funktioniert genauso, ist aber billiger.
find 4.7.0-git
).
Beachten Sie zusätzlich zu den bereits gegebenen Antworten, dass Sie Ihre Daten direkt angeben können:
find -type f -newermt "2011-12-22" \! -newermt "2011-12-24"
oder
find -type f -newermt "2011-12-22 00:00:00" \! -newermt "2011-12-24 13:23:00"
wenn Sie zusätzlich die Uhrzeit angeben möchten.
Vorausgesetzt, Sie benötigen keine sekundengenaue Genauigkeit, sollte dies funktionieren.
find . -type f -mmin -$(((`date +%s`-`date -d 20111222 +"%s"`)/60)) \! -mmin +$(((`date +%s`-`date -d 20111224 +"%s"`)/60))
EDIT: Changed cmin
bis mmin
nach @ Eelvex Kommentar.
BEARBEITEN: '\!' fehlt
-cmin
ist "Statusänderung", -mmin
ist "Datenänderung". Sie wollen wahrscheinlich-mmin
find
kann eine ISO-formatierte Datums- / Uhrzeitangabe annehmen, sodass Sie beispielsweise für einen UTC-Server einen Zeitversatz von mehreren Stunden angeben können, von dem aus Sie sich gerade befinden. Dadurch muss auch ein Tag hinzugefügt werden, da Sie auch die Zeit vergleichen:
find -type f -newermt 20111224T0800 \! -newermt 20111225T0800
Bitte beachten Sie, dass die als Duplikat markierte Frage nicht direkt beantwortet werden kann. Deshalb poste ich hier. Diese Antwort dient zur Beantwortung der Frage "Dateien müssen je nach Erstellungsdatum in einen anderen Ordner verschoben werden [duplizieren]".
Die Antworten sind vernünftig, aber es gab einige Einschränkungen bei einem reinen Suchbefehl. Ich habe dieses Shell-Skript geschrieben, um durch ein Verzeichnis mit so vielen Dateien zu gehen, dass das Dateisystem die Metadaten abfragt, um ein ls auszuführen. Außerdem wird auf einigen * nix-Systemen beim Ausführen von ls ein Fehler mit zu vielen Argumenten angezeigt.
Der Befehl find ist sehr mächtig und ich habe mit den aufgelisteten Methoden begonnen, aber ich hatte so viele Jahre an Daten in diesem Verzeichnis, dass ich alle Dateien wiederholt durchlaufen musste. Dies erzeugt eine Menge unnötiger Übergänge über jede Datei. Ich habe versucht, einen Bildschirm pro Jahr zu erstellen und mehrere Suchvorgänge auszuführen. Dies führte jedoch zu vielen Fehlern bei den einzelnen Suchvorgängen, und Dateien gingen verloren, wenn einer der Suchvorgänge verschoben wurde.
Mein Shell-Skript verschiebt eine Datei mit einem vierstelligen Jahr und einem zweistelligen Monat in das Zielverzeichnis. Es kann leicht auf einen zweistelligen Tag erweitert werden, indem ein paar Zeilen auskommentiert und ihre Gegenstücke auskommentiert werden. Ich glaube, es ist effizienter, weil es die Bewegungen in einem Durchgang der Suche durchgeführt hat, so dass mehrere Suchbefehle und Durchgänge über das Verzeichnis nicht erforderlich sind.
#!/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
Einmal gespeichert und ausführbar gemacht, können Sie dieses Skript mit find wie folgt aufrufen.
find /path/to/directory -type f -exec /home/username/move_files.sh {} \;
Sie müssen sich nicht um die Einstellung der Option newermt für find kümmern, da find nur eine Ausführung pro gefundener Datei bereitstellt und das Skript alle Entscheidungen trifft.
Denken Sie daran, dass, wenn Sie -type f nicht auswählen, Verzeichnisse verschoben werden und dies wahrscheinlich Probleme verursacht. Sie können auch -type d verwenden, wenn Sie nur Verzeichnisse verschieben möchten. Wenn Sie den Typ nicht festlegen, wird dies mit ziemlicher Sicherheit zu unerwünschtem Verhalten führen.
Denken Sie daran, dass dieses Skript auf meine Bedürfnisse zugeschnitten wurde. Vielleicht möchten Sie einfach mein Konstrukt als Inspiration für ein für Ihre Bedürfnisse besser geeignetes Skript verwenden. Danke!
Überlegungen: Die Effizienz des Befehls kann erheblich verbessert werden, indem eine unbegrenzte Anzahl von Argumenten durch das Skript geleitet wird. Dies ist relativ einfach, wenn Sie die Variable $ @ übergeben. Wenn Sie die Funktionalität erweitern, können Sie beispielsweise die Funktion -exec + von find verwenden oder xargs nutzen. Ich kann das schnell umsetzen und meine eigene Antwort verbessern, aber das ist ein Anfang.
Da dies eine einmalige Skriptsitzung war, können wahrscheinlich viele Verbesserungen vorgenommen werden. Viel Glück!