Як перелічити файли, які були змінені за певний проміжок часу?


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".
Жил "ТАК - перестань бути злим"

Ok заперечення працює над командою після. Що було б, якби заперечення не було?
Олександр Цска

@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 день! І це рекурсивно. Він добре працює на пошуку v4.5.9.


Класна хитрість, дякую! Це допомогло мені знайти останній файл, що містить певне ключове слово в каталозі з тисячами файлів: find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l( -m 50= пошук у перших 50 рядках).
Роб Ш

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

Мені довелося додавати часові позначки подвійною цитатою (я на Ubuntu Xenial find 4.7.0-git).
ІсаакS

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 в. Редагувати: '\!' зниклий безвісти


Хм, здається, не працює. ви впевнені, що він рекурсивно проходить через підкаталоги?
затискач

Так, це працює на мене. У вас дійсно є файли, змінені в цьому часовому діапазоні? Спробуйте це в різних часових діапазонах.
onur güngör

6
-cminє "зміна статусу", -mminце "зміна даних". Ви, мабуть, хочете-mmin
Евенкс

3

findможе прийняти формат дати у форматі ISO, так що, наприклад, для сервера на UTC, ви можете вказати зміщення кількості годин, де б ви не були. Для цього потрібно також додати день, оскільки ви також порівнюєте час:

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

0

Зауважте, що питання, позначене як дублікат, тому не може відповідати на нього безпосередньо, саме тому я публікую тут. Ця відповідь призначена для відповіді на питання "потрібно перемістити файли в іншу папку на основі дати створення [дубліката]"

Відповіді обґрунтовані, але були деякі обмеження із суто командою find. Я написав цей скрипт оболонки, щоб пройти каталог з такою кількістю файлів, у якій файлова система затягувала метадані, намагаючись виконати ls. Крім того, деякі * nix системи усунуть занадто багато помилок аргументів при запуску ls.

Команда find є дуже потужною, і я почав із перерахованих методів, але у мене було стільки років даних у цьому каталозі, що мені довелося повторно передавати всі файли. Це створює багато непотрібних переданих файлів у кожному файлі. Я намагався робити один екран на рік і запускати кілька знахідок, але це призводило до безлічі помилок від кожної знахідки, і файли пропали б, коли одна із знахідок перемістила його.

Мій скрипт оболонки переміщує файл у каталог призначення із чотиризначним роком та двозначним місяцем. Його можна легко розширити до двозначного дня, коментуючи пару рядків та коментуючи своїх колег. Я вважаю, що це більш ефективно, тому що виконувати рухи за один прохід пошуку, тому безліч команд пошуку та переходи через каталог не потрібні.

#!/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 /path/to/directory -type f -exec /home/username/move_files.sh {} \;

Вам не потрібно турбуватися про те, щоб встановити параметр newermt для пошуку, оскільки все знахідка - це одноразове виконання кожного знайденого файлу, і сценарій приймає всі рішення.

Майте на увазі, що якщо не вибрати -типу f, він буде переміщувати каталоги навколо, і це, ймовірно, спричинить проблеми. Ви також можете використовувати -type d, якщо хочете переміщати лише каталоги. Якщо встановити тип, майже напевно призведе до небажаної поведінки.

Пам’ятайте, що цей сценарій був пристосований до мого потреби. Ви можете просто використати мою конструкцію як натхнення для кращого підходу під ваш сценарій потреб. Дякую!

Міркування: Ефективність команди може бути ВЕЛИЧЕЗНО покращена, дозволяючи через сценарій пропускати необмежену кількість аргументів. Це насправді порівняно просто, якщо ви переходите через змінну $ @. Розширення функціональності цього дозволяє, наприклад, використовувати функцію find -exec + або використовувати xargs, наприклад. Я можу швидко реалізувати це і вдосконалити власну відповідь, але це початок.

Оскільки це був сеанс однократного сценарію, можливо, вдосконалення можна зробити багато. Удачі!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.