Как найти файлы между двумя датами с помощью «find»?

14

У меня есть учетная запись электронной почты, в которой прошло 60 ГБ писем, и в настоящее время у меня много проблем с использованием почтового клиента для архивирования электронных писем прошлого года (2011).

Через терминал я пытаюсь использовать найти , чтобы найти файлы между 2011 годом -01-01 и 2011-12-31, но не помогло.

Как найти файлы между двумя датами?

Если это необходимо, конечной целью будет пакет, который переместит каждый найденный файл, соответствующий интервалу даты, в папку.

    
задан Zuul 20.09.2012 в 20:31
источник

3 ответа

12

Вы можете использовать этот скрипт:

#!/bin/bash
for i in 'find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"'; do
        mv $i /moved_emails_dir/
done
    
ответ дан Octávio Filipe Gonçalves 20.09.2012 в 20:34
источник
25

Bash найти файлы между двумя датами:

find . -type f -newermt 2010-10-07 ! -newermt 2014-10-08

Возвращает список файлов с отметками времени после 2010-10-07 и до 2014-10-08

Bash найти файлы за 15 минут до:

find . -type f -mmin -15

Возвращает список файлов с отметками времени через 15 минут назад, но до сих пор.

Bash найти файлы между двумя метками времени:

find . -type f -newermt "2014-10-08 10:17:00" ! -newermt "2014-10-08 10:53:00"

Возвращает файлы с отметками времени между 2014-10-08 10:17:00 и 2014-10-08 10:53:00

    
ответ дан Eric Leschinski 08.10.2014 в 21:51
7

Перемещение файлов и запрос пользователю при наличии повторяющихся имен:

Как Subv3rsion и На примере ответов Эрика Лещински предикат -newermt выбирает файлы, измененные в последнее время, чем дата (и дополнительное время), указанная в качестве ее операнда. Поиск файлов

  • где-нибудь в srcdir (т. е. включая его подкаталоги, их подкаталоги и т. д.)
  • Последнее изменение в (например) сентябрь 2014 г.
  • и переместите их на destdir

... вы можете запустить:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -i {} destdir/ \;

В выражении -exec find находит имя файла вместо {} . ; означает -exec , что все команды были предоставлены (в случае, если последующие выражения передаются для поиска после тех конкретных аргументов предиката -exec - см. ниже пример) , ; должно быть экранировано как \; , поэтому оно не интерпретируется специально оболочкой. (Без \ , ; завершит команду find , работая так же, как и в новой строке. Хотя эта команда find ничего не имеет после этого выражения -exec , неспособная передать аргумент ; все еще синтаксическая ошибка.)

Если вы просто хотите перечислить файлы, что желательно, если вы не знаете, как хранятся старые электронные письма или какие другие файлы могут присутствовать, опустите -exec и все, что находится справа от него. (Для электронной почты часто электронные письма с разных дат хранятся в файле same , для кого-то в ситуации, описанной в этом вопросе, я рекомендую изучить, как они хранятся перед перемещением любых файлов.) Если вы хотите чтобы напечатать имена и переместить их, добавьте -print до -exec .

mv -i запрашивает в любое время, когда файл будет перезаписан в пункте назначения, например, если:

  • файл с тем же именем существует из предыдущей резервной копии, или
  • файл с тем же именем, но из другого подкаталога srcdir уже был перемещен во время той же самой операции find , или
  • (наименее вероятно) файл с тем же именем был создан где-то в srcdir во время той же самой операции find после того, как оригинал был перемещен, но достаточно скоро, чтобы его можно было найти один раз find пересекает другой подкаталог.

Другие способы вызова rm :

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

  • Без -i (т. е. mv {} destdir/ ), mv обычно не запрашивает утверждение, но сделает это, если целевой файл будет доступен только для чтения. ( mv может даже преуспеть в том, чтобы иногда перезаписывать файл только для чтения, например, если пользователь, которому он принадлежит, принадлежит файл.)
  • Если вы не хотите даже такой степени интерактивности и хотите, чтобы mv всегда (пытались) перезаписать файлы с одинаковым именем, используйте mv -f .
  • Если, напротив, вы хотите пропустить исходные файлы, когда уже есть файл назначения с тем же именем, используйте mv -n .
  • mv принимает флаги -b и --backup для автоматического переименования файлов с идентичным именем, которые уже существуют в пункте назначения. По умолчанию ~ добавляется для создания имени резервной копии, и если файл с именем и файлом с именем резервной копии уже существует в месте назначения, файл резервной копии перезаписывается. Это значение по умолчанию может быть переопределено параметрами, передаваемыми при вызове mv и переменными окружения. Подробнее см. man mv и пример ниже.

Перемещение файлов и создание резервных копий в случае дубликатов имен:

Чтобы переместить все файлы, создайте резервные копии файлов с повторяющимися именами, используя суффикс ~ , и используйте суффиксы .~n~ , когда .~ файлов уже существуют (чтобы не перезаписывать что-либо), запустите:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv --backup=existing {} destdir/ \;

Если вы пропустили файлы с повторяющимися именами и хотите узнать, какие из них:

Если вы используете mv -n и хотите знать, какие файлы не были перемещены, потому что там был другой файл с тем же именем, лучшим способом, вероятно, является просто запуск исходной команды find , без -exec и всего справа от него. Это будет напечатать их имена.
Он также напечатает имена любых совпадающих файлов, созданных с момента запуска исходной команды find .... -exec ... , но для этого приложения, как правило, не будет никаких, поскольку вы ищете файлы с старый модификация раз. Можно предоставить файл временную метку модификации старше своего реального возраста с touch и другими механизмами, но это вряд ли произойдет в этом случае без вашего ведома.

Зная сразу, как файлы пропускаются из-за дубликатов имен:

mv -n не сообщает и не возвращает какой-либо специальный код выхода , когда он воздерживается от перемещения файла.Поэтому, если вы хотите получить немедленную информацию о пропущенных файлах, в то время как find работает, вам придется сделать отдельный шаг для этого. Один из способов:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -n {} destdir/ \; \
    -exec [ -f {} ] \; -exec printf "\'%s' skipped (exists in \'%s')\n" {} destdir \; 

Несколько возможных незначительных технических соображений: Это неверно предупреждает, если mv не удалось скопировать файл по другой причине, чем существующая в целевом , и выходит из . Это кажется маловероятным, но я не уверен, что это невозможно. Он также потенциально страдает состоянием гонки : он будет предупреждать, когда вообще нет реальной ошибки, если новый файл одно и то же имя было создано в том же месте в течение очень короткого времени после того, как старый файл был перемещен, и перед проверкой, был ли он удален. (Учитывая приложение, я сомневаюсь, что любая проблема когда-либо возникнет.) Его можно было бы переписать, чтобы проверить назначение перед перемещение файла, а не после: тогда условие гонки будет относиться только к вновь созданным файлам назначения исходных файлов. И хотя ошибки и предупреждения, сообщенные find или mv (или [ , хотя их не должно быть), будут записаны в стандартная ошибка , наше предупреждение ...skipped (exists in... записывается в стандарт выход . Обычно оба отображаются на вашем терминале, но это может иметь значение, если вы работаете с скриптами.

Я разделил эту команду на две строки для упрощения чтения. Его можно запустить таким образом, или вы можете удалить \ и новую строку (т. Е. Разрыв строки).

Как работает эта команда find ?

% предикатов co_de% могут быть tests (например, find и -type ), используемые для их возвращаемых значений или действия (например, -newermt и -print ), которые часто используются для их побочных эффектов.

Если между выражениями не указан оператор (например, -exec для и , -a для или ), подразумевается -o . -a использует оценку короткого замыкания для и и или EM>. find (т. е. p q ) истинно, только если выражения p и q являются истинными, поэтому q не обязательно если p является ложным. Хотя мы часто не думаем об этом в этих терминах, именно поэтому тесты должны быть верны для последующих действий или тестов, которые должны быть оценены. Например, предположим, что p -a q попадает в каталог. Он оценивает find на false, поэтому после этого он может пропустить все.

Как и тесты, действия также оцениваются как true, так и false. Таким образом, -type f сообщает, что выполненная команда завершила успешную отчетность (true) или сбой (false). У нас есть эта цепочка из -exec выражений, связанных с неявными и :

-exec mv -n {} destdir/ \; -exec [ -f {} ] \; -exec printf "\'%s' skipped (exists in \'%s')\n" {} destdir \;

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

Но если это сработает, тогда будет выполняться команда mv , Как [ , find поддерживает свои собственные выражения, переданные в качестве аргументов. [ проверяет, существует ли операнд после [ -f {} ] (переданный ему -f вместо find ) и (или является обычным файлом) и возвращает либо true / success, либо false / failure.
< sub> (Статусы выхода многих команд лучше всего интерпретировать как означающие успех или неудачу, но статус статуса {} обычно лучше всего интерпретировать как true или false.)

Если [ вернул false, файл исчез, поэтому он был перемещен, поэтому ничего не нужно делать. Но если [ возвратил false, файл все еще существует. Затем [ оценивает следующее выражение find , которое печатает предупреждающее сообщение.

Дополнительная литература

ответ дан Eliah Kagan 09.10.2014 в 03:46