I'm trying to copy all media files (Mac file type of Image or Movie) to the same directory structure, only taking media files.

  1. Is there a more efficient way than what I've got below?
  2. Is there a mechanism in Mac OS find to get the type of Image or Movie?
  3. Can this be done without an intermediate tar file? (assume 100,000 media files)

Idea is to:

  1. Create temporary file list of media files (tar can't take that many files at command line)
  2. Create tar file
  3. Extract tar file

Thanks for any advice.

# $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 Answer 1


Different options:

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

  • parallel can be installed with brew install parallel
  • {/} is the basename

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

  • read strips characters in IFS from the start and end of lines
  • read -r disables interpreting backslashes
  • ${f%%*/} removes the longest */ pattern from the start

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

  • globstar (added in bash 4.0) makes ** match multiple levels of directories
  • extglob adds support for @(pat1|pat2) (exactly one)
  • nocaseglob makes globs case-insensitive

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's find doesn't support extended regex, so the command uses GNU find
  • export -f and bash -c are needed to run the function with xargs
  • xargs -n1 takes one argument at a time
  • There's no parallel on OS X by default. It'd also help if you explained what these options do.
    – Daniel Beck
    Jun 16, 2013 at 17:49
  • It would be great to list the pros and cons of those, especially with external USB drives with huge numbers of files. Jun 16, 2013 at 22:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.