Как вывести список файлов, которые были изменены за определенный промежуток времени?


38

Как я могу рекурсивно перечислить все файлы, которые были изменены с 22.12.2011 по 24.12.2011?


6
Если вы имеете в виду «последнее изменение», у вас есть шанс найти решение. Если файл был изменен 26.12.2011, вы не можете сказать, был ли он также изменен в заданном диапазоне. (Если у вас нет очень экзотической файловой системы.)
Уильям Перселл

Ответы:


25

Вообще говоря, когда вы ищете файлы в каталоге и его подкаталогах рекурсивно, используйте find.

Самый простой способ указать диапазон дат find- создать файлы на границах диапазона и использовать -newerпредикат.

touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop

почему отрицание вывода первого -newerнеобходимо здесь?
Александр Цска

@AlexanderCska Первый -newerне отрицается, второй. «Найти файлы, которые новее, чем, startно не новее, чем stop».
Жиль "ТАК - перестань быть злым"

ОК отрицание работает по команде после. Что бы произошло, если бы не было отрицания?
Александр Цска

@AlexanderCska Тогда вы получите файлы, которые новее, чем оба startи stop.
Жиль "ТАК - перестань быть злым"

35

Используя решение Жиля, и после прочтения мужчина снова нашел (1), я нашел более простое решение. Лучшим вариантом является -newerXY. Можно использовать флаги m и t.

m   The modification time of the file reference
t   reference is interpreted directly as a time

Так что решение

find . -type f -newermt 20111222 \! -newermt 20111225

Нижняя граница включительно, а верхняя граница исключительна, поэтому я добавил к ней 1 день! И это рекурсивно. Хорошо работает на find v4.5.9.


Прикольный трюк, спасибо! Это помогло мне найти недавний файл, содержащий определенное ключевое слово в каталоге с тысячами файлов: find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l( -m 50= поиск в первых 50 строках).
Роб W

@RobW: На самом деле вы можете сэкономить трубу и xargs , используя -exec ... +в find(1), как: find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +. Это делает то же самое, но дешевле.
Правда,

Мне пришлось заключить временные метки в двойные кавычки (я в Ubuntu Xenial с find 4.7.0-git).
Исаак

13

В дополнение к уже даным ответам, обратите внимание, что вы можете напрямую указать свои даты:

find -type f -newermt "2011-12-22" \! -newermt "2011-12-24"

или

find -type f -newermt "2011-12-22 00:00:00" \! -newermt "2011-12-24 13:23:00"

если вы дополнительно хотите указать время.


6

Предполагая, что вам не нужна точность до секунд, это должно сработать.

find . -type f -mmin -$(((`date +%s`-`date -d 20111222 +"%s"`)/60)) \! -mmin +$(((`date +%s`-`date -d 20111224 +"%s"`)/60))

EDIT: Изменены cminк mminпосле @ комментарий Eelvex в. РЕДАКТИРОВАТЬ: '\!' отсутствует


хм не похоже на работу. Вы уверены, что он рекурсивно идет по подкаталогам?
зажим

Да, это работает на меня. Вы действительно изменили файлы за этот промежуток времени? Попробуйте это с разными временными диапазонами.
Онур Гюнгёр

6
-cminэто «изменение статуса», -mminэто «изменение данных». Вы, вероятно, хотите-mmin
Eelvex

3

findМожно использовать формат даты и времени в формате ISO, поэтому для сервера, например, в формате UTC, вы можете указать смещение количества часов, где бы вы ни находились. Это также позаботится о том, чтобы добавить день, так как вы тоже сравниваете время:

find -type f -newermt 20111224T0800 \! -newermt 20111225T0800

0

Пожалуйста, обратите внимание, что вопрос, помеченный как дубликат, и поэтому ограничен от прямого ответа, поэтому я публикую здесь. Этот ответ предназначен для ответа на вопрос «необходимо переместить файлы в другую папку на основе даты создания [дубликата]»

Ответы разумны, но с чисто командой поиска были некоторые ограничения. Я написал этот сценарий оболочки, чтобы пройти через каталог с таким количеством файлов, что файловая система давала метаданные, пытаясь выполнить ls. Кроме того, некоторые системы * nix будут выдавать ошибку слишком многих аргументов при запуске ls.

Команда find очень мощная, и я начал с перечисленных методов, но у меня было столько лет данных в этом каталоге, что мне приходилось многократно проходить по всем файлам. Это приводит к большому количеству ненужных передаваемых файлов. Я пытался делать один экран в год и запускать несколько находок, но это приводило к большому количеству ошибок в каждой находке, и файлы терялись, когда одна из находок перемещала ее.

Мой сценарий оболочки перемещает файл в каталог назначения с 4-значным годом и 2-значным месяцем. Его можно легко расширить до двухзначного дня, раскомментировав пару строк и закомментировав их аналоги. Я считаю, что он более эффективен, потому что он выполнял шаги за один проход поиска, поэтому несколько команд поиска и проходов по каталогу не нужны.

#!/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

После сохранения и создания исполняемого файла вы можете вызвать этот скрипт с помощью команды find следующим образом.

find /path/to/directory -type f -exec /home/username/move_files.sh {} \;

Вам не нужно беспокоиться об установке параметра newermt для find, поскольку все, что находит find, - это одно выполнение для каждого найденного файла, и скрипт принимает все решения.

Имейте в виду, что если вы не выберете -type f, это приведет к перемещению каталогов, что может вызвать проблемы. Вы также можете использовать -type d, если хотите переместить только каталоги. Отсутствие установки типа почти наверняка приведет к нежелательному поведению.

Помните, что этот сценарий был адаптирован к моим потребностям. Возможно, вы захотите просто использовать мою конструкцию как источник вдохновения для лучшего сценария ваших потребностей. Спасибо!

Соображения: эффективность команды может быть БОЛЬШО повышена за счет разрешения неограниченному количеству аргументов проходить через скрипт. На самом деле это относительно просто, если вы передадите переменную $ @. Расширение функциональности этого позволило бы нам использовать, например, функцию find -exec + или использовать xargs. Я могу быстро реализовать это и улучшить свой собственный ответ, но это только начало.

Поскольку это был сеанс сценария с одним выстрелом, вероятно, можно сделать много улучшений. Удачи!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.