Passing a result from one line of a shell script to the next.

mdls lists metadata attributes of a file: mdls -onlyin ~/aDirectory Posix/Path/To/File.

mdfind finds a file given some attribute or attributes, and it returns a posix path to the file (without quotes)

How can I find a file path with spaces in it (using mdfind), get quotes around it because it contains spaces, and then use it in an mdls instruction which insists on having the file path appended. mdls will not accept piping the find to it, and won’t accept the find command in back ticks appended to it either (it tries to read the instruction).

Obviously I could do this with two shell script calls, storing the path in a variable and passing it to mdfind & quoted forme of myVar but that seems a waste of a shell call. It even works as a one liner:

do shell script "mdls [some attribute] " & quoted form of (do shell script “mdfind -onlyin someDirectory "theQueryString”), but that’s still two shell calls. :frowning:

Edit: Well, I made this script because I used to have problems using Spotlight with disk images. However, Spotlight seems to be working great now. :rolleyes:

Edit: This is kinda lengthy; I’ll remove it and post something more specific below.

I think I’m stuck with:

set F to do shell script "mdfind -onlyin ~/Music 'When You Say Nothing At All'"
set MetaData to (do shell script "mdls " & quoted form of F)

which I understand, but thanks anyway.

I’ll be 70 this year; maybe that’s it.:confused:

EDIT: Your full script didn’t work for me either. The choose comment box came up blank, even though I had commented a couple of folders on my desktop.

Consider this:

do shell script "/usr/bin/mdfind -onlyin ~/Music 'When You Say Nothing At All'" & ¬
	" | /usr/bin/sed 's/\\ /\\\\\\ /g'" & ¬
	" | /usr/bin/xargs /usr/bin/mdls"

Steps:
1) We are using Spotlight (mdfind) to find files with a certain phrase in their filename.

2) We are using sed to escape all spaces in the output (which consists of unescaped POSIX paths). Not only is this needed to escape the files names, it is also needed for xargs.

3) mdls will not accept multiple lines from stdin; Instead, we will use xargs to call mdls for each “item” of output from the first step. Note that, by default, xargs delimits items by spaces and newlines; Because we escaped the spaces in our filenames, xargs will read it’s input the way we intended it to.

This appears to work:

set query to "\"keychain\""
set findPath to "/Applications/"
do shell script "mdls -name kMDItemKind \"`mdfind -onlyin " & quoted form of findPath & space & quoted form of query & "`\""

Qwerty, try using a query that returns more than one item.

set query to "\"access\""
set findPath to "/Applications/"
do shell script "mdls -name kMDItemKind \"`mdfind -onlyin " & quoted form of findPath & space & quoted form of query & "`\""

Edit: It seems that mdls will take unescaped paths. After setting xargs to uses null bytes (ASCII character 0)as delimiters, I replaced the new lines with null bytes and left the spaces unescaped.

do shell script "/usr/bin/mdfind -onlyin ~/Music 'When You Say Nothing At All'" & ¬
	" | /usr/bin/ruby -e 'STDIN.each {|line| print line.sub(\"\\n\", \"\\0\")}'" & ¬
	" | /usr/bin/xargs -0 /usr/bin/mdls"

This is how I finally did it. As Bruce points out, it will fail if the mdfind argument returns multiple results, so an error means that the search argument was not specific enough.


set Q to "a song title" as Unicode text
set MD to do shell script "F=`mdfind -onlyin ~/Music " & quoted form of Q & "`;mdls \"$F\""

I never thought of using it like that. Good idea!

Here’s an example of how I use it (to appear in next week’s MacScripter tutorial to follow Craig Smith’s “AppleScript Tutorial for Beginners VI - User Interaction” which is running now - pardon the plug :)):

set Q to (text returned of (display dialog "Enter a Unique Song Title" default answer "Song Title Here" with title "Find Last Played Date") as Unicode text)
try
	set LastPlayed to last paragraph of (do shell script "F=`mdfind -onlyin ~/Music " & quoted form of Q & "`;mdls -name kMDItemLastUsedDate  \"$F\"")
on error
	display dialog "Title \"" & Q & "\" was not found or was not sufficiently unique to return a single result."
	return
end try
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "kMDItemLastUsedDate = "
set E to text item 2 of LastPlayed
set AppleScript's text item delimiters to space
set F to text items of E
set AppleScript's text item delimiters to tid
set tDate to reverse of (words of item 1 of F)
set AppleScript's text item delimiters to "/"
set tDate to tDate as text
set AppleScript's text item delimiters to tid
set tTime to item 2 of F
display dialog "\"" & Q & "\"" & " was last played on" & return & tDate & " at " & tTime