У меня есть IP-камера, которая сохраняет свои записи в моей папке Samba. Я хочу скопировать эти файлы в другое место, как только они будут полностью сохранены.

Теперь моя проблема: камере требуется некоторое время, чтобы скопировать файлы в формате .avi (с именем motion-date.avi) в мой общий ресурс, при этом он также создает файл .idx (с именем motion-date.idx) с тем же именем, которое будет удалено, как только это будет сделано.

Поэтому я хочу скопировать все файлы .avi , у которых нет соответствующего файла .idx , в другую папку.

1 ответ1

1
find /source/dir/ -type f -name '*.avi' -exec sh -c 'f="{}"; test ! -f "${f%.*}.idx" && cp "$f" /target/dir/' \;

Эта команда находит все файлы .avi в /source/dir/ и порождает базовую оболочку для каждого из них. Затем оболочка проверяет, не существует ли соответствующий файл .idx и при необходимости вызывает cp .


Изменить: я немного изменил команду, чтобы сделать ее более надежной. По явному запросу я объясняю всю команду более подробно.

  • find - найти ...
  • /source/dir/ - ... в данном каталоге ...
  • -type f - ... все файлы ...
  • -name '*.avi' - ... с именами, соответствующими этому шаблону ...
  • -exec - ... и для каждого найденного файла выполнить ...
  • sh ... - ... оболочка со своими параметрами (объяснено позже).
  • \; - Это указывает, где заканчивается -exec . Важный трюк: каждая строка {} заменяется фактическим путем к найденному файлу; так работает find -exec .

Каждая оболочка получает опцию -c , которая указывает ей выполнить следующий аргумент, как это была набранная команда. Оболочка видит эту команду с {} уже замененным путем к файлу, как объяснено выше.

И команда идет так:

  • f="{}" - Запомните путь под именем f (помните: на данный момент уже есть некоторый путь вместо {}).
  • ; - Разделитель команд.
  • test - соответственно проверить и вернуть статус выхода; следующие аргументы скажут, что тестировать.
    • ! - Внимание: тест полностью изменен.
    • -f - проверить, существует ли файл ...
    • "${f%.*}.idx" - ... по этому пути. Конструкция ${f%.*} Говорит оболочке получить содержимое переменной f без фрагмента из последней точки . к концу. Я добавляю еще одно расширение. Таким образом, я обмениваю их.
  • && - Только если предыдущая команда (т.е. test) вернула статус выхода 0 ...
  • cp - ... копировать ...
    • "$f" - ... файл, который был найден командой find ...
    • /target/dir/ - ... в целевой каталог.

Финальные заметки:

  • Мне нужна оболочка, чтобы позаботиться о "${f%.*}.idx" и && . Если я хочу скопировать каждый найденный файл, то ... -exec cp "{}" /target/dir/ \; было бы достаточно (и все же далеко от оптимального, но давайте не будем отвлекаться).
  • Хорошо указывать (например, "") каждый путь, который может включать пробелы, специальные символы и т.д.
  • Аргумент (команда) для sh в одинарные кавычки (''). Если if было в двойных кавычках (""), расширение "${f%.*}.idx" будет происходить в текущей оболочке (той, которая запускает find), и это не то, что я хочу. Вы можете прочитать больше здесь .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .