Я пытаюсь скопировать все медиа-файлы (Mac-файлы типа «Изображение» или «Фильм») в одну и ту же структуру каталогов, используя только медиа-файлы.

  1. Есть ли более эффективный способ, чем у меня ниже?
  2. Есть ли в Mac OS механизм поиска типа изображения или фильма?
  3. Можно ли это сделать без промежуточного файла tar? (предположим, 100 000 медиа-файлов)

Идея состоит в том, чтобы:

  1. Создать временный список файлов мультимедиа (tar не может взять столько файлов в командной строке)
  2. Создать файл tar
  3. Извлечь файл tar

Спасибо за любой совет.

# $1 is the directory to search for media
# $2 is the output file name
media_list() {
  find $1 -type f \( -iname "*.JPG" -o -iname "*.JPEG" -o -iname "*.NREF" -o -iname "*.TIFF" -o -iname "*.wmv" -o -iname "*.MOV" -o -iname "*.mp4" -o -iname "*.MPG" -o -iname "*.AVI" -o -iname "*.3g2" -o -iname "*.3gp" -o -iname "*.m4v" \) > $2
}

# $1 is the directory to get media
# $2 is the output tar file name
tar_media() {
  rm file-list.txt
  media_list $1 file-list.txt
  tar -cv -f $2 -I file-list.txt 
}

1 ответ1

1

Различные варианты:

mdfind -onlyin . 'kMDItemContentTypeTree=public.movie||kMDItemContentTypeTree=public.image' | parallel cp {} /tmp/{/}

  • Параллельно может быть установлен с brew install parallel
  • {/} является базовым именем

find . -iname \*.mkv -o -iname \*.jpg | while IFS= read -r f; do cp "$f" /tmp/"${f%%*/}"; done

  • читать символы полос в IFS с начала и до конца строк
  • read -r отключает интерпретацию обратной косой черты
  • ${f%%*/} удаляет самый длинный шаблон */ с самого начала

shopt -s globstar extglob nocaseglob; for f in **/*.@(mkv|jpg); do cp "$f" "/tmp/${f%%*/}"; done

  • globstar (добавлен в bash 4.0) позволяет ** соответствовать нескольким уровням каталогов
  • extglob добавлена поддержка @(pat1|pat2) (ровно один)
  • nocaseglob делает глобусы нечувствительными к регистру

f() { cp "$1" "/tmp/${1%%*/}"; }; export -f f; gfind . -regextype posix-extended -iregex '.*\.(mkv|jpg)' -print0 | xargs -0 -n1 bash -c 'f "$1"' _

  • OS X find не поддерживает расширенное регулярное выражение, поэтому команда использует GNU find
  • Для запуска функции с помощью xargs необходимы команды export -f и bash -c
  • xargs -n1 принимает один аргумент за раз

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