У меня есть учетная запись электронной почты, которая отправила 60 ГБ писем, и в настоящее время у меня много проблем с использованием почтового клиента для архивирования писем прошлого года (2011).
Через терминал я пытаюсь использовать find , чтобы найти файлы между 2011-01-01 и 2011-12-31, но безрезультатно.
Как мне найти файлы между двумя датами?
Если уместно, конечной целью будет пакет, который будет перемещать каждый найденный файл, соответствующий интервалу дат, в папку. Sup >
Вы можете использовать этот скрипт:
#!/bin/bash
for i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do
mv $i /moved_emails_dir/
done
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
Как Subv3rsion и Ответы Эрика Лещинского показывают, что -newermt
выбирает файлы, измененные позже, чем дата (и необязательно время), указанная в качестве его операнда.Чтобы найти файлы
srcdir
(т.е. включая его подкаталоги, их подкаталоги и т. Д.) 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
, которое выводит предупреждение.
man find
и справочное руководство GNU Findutils man mv
и справочное руководство GNU Coreutils (особенно 11.4 mv
: перемещение (переименование) файлов ) man \ [
] и 16.3: проверьте типы файлов и сравните значения в документации Coreutils / usr / bin / [
), а не [
встроенный , это то, что find
запускается при использовании -exec [
.