Как найти файлы между двумя датами, используя & ldquo; find & rdquo ;?

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

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

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

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

32
задан 1 May 2015 в 20:31

3 ответа

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

#!/bin/bash
for i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do
  mv $i /moved_emails_dir/
done
20
ответ дан 1 May 2015 в 20: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

54
ответ дан 1 May 2015 в 20:31

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

Как 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 и все, что находится справа от него. (Что касается электронной почты, часто электронные письма с разными датами хранятся в одном и том же файле ; тем, кто попал в ситуацию, описанную в вопросе здесь, я рекомендую изучить, как они хранятся, прежде чем перемещать какие-либо файлы.) Если вы хотите оба печатают свои имена и перемещают их, добавьте -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 (или [, хотя их не должно быть), они будут записаны в стандартную ошибку , наше ... пропущено (существует в ... предупреждение записывается в стандартный вывод . Обычно оба появляются на вашем терминале, но это может иметь значение, если вы пишете сценарий.

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

Как работает ли эта команда find ? Предикаты

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

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

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

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

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

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

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

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

13
ответ дан 1 May 2015 в 20:31

Другие вопросы по тегам:

Похожие вопросы: