MacOS – How to properly esca‌​pe spaces in the res‌​ults of mdfind to use them in a for loop

bashmacosscriptspotlight

Trying to answer the question Are true dynamic folders (NOT a “Smart Folder” SavedSearch) possible? I stumbled about the problem to loop the results of an mdfind search as quoted or escaped paths.

Code snippet:

for File in $(mdfind -onlyin $MusicSamples 'kMDItemAudioBitRate >= "44000"  && _kMDItemUserTags = "Sample"')
do
    ln -s $File $DrumFoldr
done

The for loop should create soft links of all matching files in the folder $MusicSamples or its sub folders in the folder $DrumFoldr. The loop works for files with paths/file names without spaces.

  • The answer to a similar question simply suggests to quote $File (... "$File" ...). This doesn't work – it simply creates broken soft links with names of the contiguous strings in the original file name: a file named "1. Artist – Song – Mix.mp3" will create four or five soft links: "1.", "Artist", "Song", "Mix.mp3" and "-".

  • Escaping the spaces by piping the mdfind results to a sed command replacing a space with an escaped space will result in something like "\ 1.", "\ Artist" etc.

  • Creating an array of the mdfind results with:

    result=()
    mdfind ... | while IFS= read -r filename; do
      result+=("$filename")
    done
    

    and using it in for File in "${result[@]}"; do ln -s "$File" $DrumFoldr; done doesn't work either.

How do I properly escape those spaces in the paths?

Best Answer

I just solved a similar problem as I was trying to iterate over mdfind's results of an image search.

counter=0
mdfind image -onlyin $1 | while read line; do 
    ((counter = counter + 1))
    echo "$counter: $line"
done
exit

So adapting that to your problem, this should work:

mdfind -onlyin $MusicSamples 'kMDItemAudioBitRate >= "44000" && _kMDItemUserTags = "Sample"' | while read File
do
    ln -s $File $DrumFoldr
done