Как я могу переместить или удалить файлы, созданные за определенный промежуток времени?

227
Tim

Я снимаю фильмы с интервалом в несколько недель и хочу избавиться от снимков, сделанных ночью (например, с 22:45 до 5:00), как я могу сделать это легко?

Я нашел следующие частичные решения:

  • Использование find -newerXYи, в частности, -newermtбыло бы возможно, но требует, чтобы я перебрал все даты,
  • Использую statдля запроса mtime, но я не знаю, как легко сравнивать времена в bash.

Сейчас я делаю это вручную, но я уверен, что должно быть более элегантное решение. Есть идеи? Спасибо! :)

0

2 ответа на вопрос

1
Kamil Maciorowski

Эта полу-одиночная строка напечатает «ночные» файлы:

( \ 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 \ ) 

Подстроки объяснили:

  1. Запускает подоболочку, чтобы сделать переменные локальными.
  2. Вычисляет нижний предел в минутах после полуночи.
  3. Рассчитывает верхний предел.
  4. Для каждого файла выполняется отдельный файл bash; это сделает арифметику.
  5. Извлекает mtime как HH:MM.
  6. Преобразуется HH:MMв значение в минутах после полуночи.
  7. Сравнивает это значение с предварительно рассчитанными пределами.
  8. Это аргументы для внутреннего bash; внутри, они называются $0, $1, $2.
  9. Печатает путь, если предыдущий тест возвращает true.
  10. Заканчивает подоболочку.

Некоторые замечания:

  • -execможет выступать в качестве теста при findвызове. Это вряд ли очевидно, но очень сильно. В этом случае проверка верна, когда последняя часть внутренней bashкомандной строки (т. Е. test) Возвращает истину (т. Е. Ее состояние выхода равно 0).
  • Bash arithmetic ( $((…))) разбирает 01или около того восьмеричное число, 08и 09является недопустимым восьмеричным числом. Вот почему нам нужно использовать, 10#чтобы все числа, извлеченные из statвывода, интерпретировались как десятичные.
  • Я использовал -ltи -gtв test. Используйте -leи / или -geесли они вам больше подходят.
  • Для удаления файлов замените -printна -delete(или используйте их вместе:) -print -delete.
  • Чтобы переместить файлы в один каталог заменить -printс -print0и построить трубу, как это:

    ( … find … -print0 ) | xargs -0r mv -t /target/directory/ 
1
xenoid

С 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 '^. (22:4[5-9]|22:5|23:|0[0-4]:)'чтобы избежать ложных попаданий.
Предупреждение: возможно, он работал для OP, но следует отметить, что если в его * filename * есть файл с совпадающей строкой (например, `foo 23: bar`), он будет перемещен независимо от его mtime. Другая проблема: соответствующий файл, у которого есть новая строка в имени файла, не будет перемещен, я думаю. Kamil Maciorowski 7 лет назад 0
Регулировка регулярного выражения была оставлена ​​читателю в качестве упражнения. Если у вас есть файлы с символами новой строки в их именах, у вас очень печальная система и множество других проблем, которые нужно решить, прежде чем задуматься об этом :) xenoid 7 лет назад 0

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