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

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

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

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

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

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

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

#!/bin/bashfor i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do  mv $i /moved_emails_dir/done

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

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

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

...ты можешь бежать:

find srcdir - тип f-newermt 2014-08-31 ! -newermt 2014-09-30-exec mv-i {} дестдир/ \;

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

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

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

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

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

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

  • Без -i (т.е., mv {} дестдир/), 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 {} дестдир/ \;

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

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

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

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

find srcdir - тип f-newermt 2014-08-31 ! -newermt 2014-09-30-exec mv-n {} дестдир/ \; \    -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} дестдир \; 

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

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

Как это происходит find командная работа?

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

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

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

-exec mv -n {} дестдир/ \; -исполнитель [ -f {} ] \; -исполнитель printf "\`%s' пропущено (существует в \`%s')\\n" {} дестдир \;

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

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

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

Дальнейшее чтение

@EliahKagan В то время, если мне не изменяет память, дублированные имена не были проблемой. Тем не менее, если вы считаете, что у вас есть время, дополнительная информация по любому вопросу всегда приветствуется :slight_smile: Кроме того, я поддержал ваш ответ, поскольку он дает дополнительную информацию по этой теме.

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