Как я могу переместить или удалить файлы, созданные за определенный промежуток времени?
Я снимаю фильмы с интервалом в несколько недель и хочу избавиться от снимков, сделанных ночью (например, с 22:45 до 5:00), как я могу сделать это легко?
Я нашел следующие частичные решения:
- С помощью
find -newerXY
и конкретно-newermt
было бы возможно, но требует, чтобы я перебрал все даты, - С помощью
stat
запросить Mtime, но я не знаю, как легко сравнить времена в Bash.
Сейчас я делаю это вручную, но я уверен, что должно быть более элегантное решение. Есть идеи? Спасибо!:)
2 ответа
Решение
С stat
(предполагается, что все файлы находятся в одном каталоге)
stat -c '%y %n' * | grep -E ' (22:4[5-9]|22:5|23:|0[0-4]:)' | cut -d ' ' -f 4 | xargs mv -t $dirForRemovedFiles
- это предполагает, что в выходных данных stat не зависит от локали (это, кажется, не...), в противном случае принудительно установите локаль в "C".
- это предполагает, что все файлы находятся в одном сегменте DST.
- обратите внимание на пробел между кавычкой и круглыми скобками, это то, что заставляет регулярное выражение соответствовать только началу метки времени.
- в целях безопасности приведенная выше команда ничего не удаляет, она просто перемещает файлы в каталог, где вы
rm *
как только вы заявили, что ничего не упускаете. - если вы параноик, используйте
grep -E '^.{10} (22:4[5-9]|22:5|23:|0[0-4]:)'
чтобы избежать ложных попаданий.
Эта полу-одиночная строка будет печатать "ночные" файлы:
( \
llimit=$((60*5+0)); \
ulimit=$((60*22+45)); \
find -type f -exec bash -c '\
hm=`stat -c "%y" "$0" | cut -c 12-16`; \
t=$((60*10#`echo $hm | cut -c 1-2`+10#`echo $hm | cut -c 4-5`)); \
test \( $t -lt $1 \) -o \( $t -gt $2 \)' \
{} $llimit $ulimit \; \
-print \
)
Подстроки объяснили:
- Запускает подоболочку, чтобы сделать переменные локальными.
- Вычисляет нижний предел в минутах после полуночи.
- Рассчитывает верхний предел.
- Для каждого файла отдельный
bash
выполнен; это сделает арифметику. - Извлекает mtime как
HH:MM
, - Обращенные
HH:MM
до значения, как минуты после полуночи. - Сравнивает это значение с предварительно рассчитанными пределами.
- Это аргументы к внутреннему
bash
; внутри они называются$0
,$1
,$2
, - Печатает путь, если предыдущий тест возвращает true.
- Заканчивает подоболочку.
Некоторые замечания:
-exec
может выступать в качестве теста вfind
призывание. Это вряд ли очевидно, но очень сильно. В этом случае тест верен, когда финальная часть внутреннегоbash
командная строка (т.е.test
) возвращает истину (то есть его статус выхода0
).- Баш арифметика (
$((…))
) разбирает01
или как восьмеричное число,08
а также09
неверны восьмеричные числа. Вот почему мы должны использовать10#
чтобы убедиться, что все числа извлечены изstat
выходные данные интерпретируются как десятичные. - я использовал
-lt
а также-gt
вtest
, использование-le
и / или-ge
если они подходят вам лучше. - Удалить файлы заменить
-print
с-delete
(или используйте их вместе:-print -delete
). Чтобы переместить файлы в один каталог, замените
-print
с-print0
и построить трубу, как это:( … find … -print0 ) | xargs -0r mv -t /target/directory/