The Power of mdfind
Pages: 1, 2, 3, 4
Summary
Remember that mdfind is a file-level utility. It finds files that match, but provides no context for them. It also only provides file-level granularity. For example, since I use Apple's Mail program, which stores individual mail messages as separate files, mdfind returns individual mail messages that match my searches. However, mail programs like Eudora store an entire folder of messages in one file in mbox format. If one message in that box matches a search, mdfind will show the file as a match, but not which message in the file made the match.
I hope you've found this overview of mdfind illuminating. Much of the information has been taken from other articles and comments around the Web, since Apple's documentation on mdfind is so sparse. Here's hoping that a future update to Tiger enhances the documentation.
Appendix A: A Summary of Common Options
From Chapter 2 of Mac OS X Tiger In A Nutshell.
- MDItemAttributeChangeDate
- The date and time that a metadata attribute was last changed.
- MDItemAudiences
- The intended audience of the file.
- MDItemAuthors
- The authors of the document.
- MDItemCity
- The document's city of origin.
- MDItemComment
- Comments regarding the document.
- MDItemContactKeywords
- A list of contacts associated with the document.
- MDItemContentCreationDate
- The document's creation date.
- MDItemContentModificationDate
- Last modification date of the document.
- MDItemContentType
- The qualified content type of the document, such as
com.adobe.pdffor PDF files andcom.apple.protected-mpeg-4-audiofor an Apple Advanced Audio Coding (AAC) file. - MDItemContributors
- Contributors to this document.
- MDItemCopyright
- The copyright owner.
- MDItemCountry
- The document's country of origin.
- MDItemCoverage
- The scope of the document, such as a geographical location or a period of time.
- MDItemCreator
- The application that created the document.
- MDItemDescription
- A description of the document.
- MDItemDueDate
- Due date for the item represented by the document.
- MDItemDurationSeconds
- Duration (in seconds) of the document.
- MDItemEmailAddresses
- Email addresses associated with this document.
- MDItemEncodingApplications
- The name of the application (such as Acrobat Distiller) that was responsible for converting the document in its current form.
- MDItemFinderComment
- This contains any Finder comments for the document.
- MDItemFonts
- Fonts used in the document.
- MDItemHeadline
- A headline-style synopsis of the document.
- MDItemInstantMessageAddresses
- IM addresses/screen names associated with the document.
- MDItemInstructions
- Special instructions or warnings associated with this document.
- MDItemKeywords
- Keywords associated with the document.
- MDItemKind
- Describes the kind of document, such as an iCal Event.
- MDItemLanguages
- Language of the document.
- MDItemLastUsedDate
- The date and time the document was last opened.
- MDItemNumberOfPages
- Page count of this document.
- MDItemOrganizations
- The organization that created the document.
- MDItemPageHeight
- Height of the document's page layout in points.
- MDItemPageWidth
- Width of the document's page layout in points.
- MDItemPhoneNumbers
- Phone numbers associated with the document.
- MDItemProjects
- Names of projects (other documents, such as an iMovie project) that this document is associated with.
- MDItemPublishers
- The publisher of the document.
- MDItemRecipients
- The recipient of the document.
- MDItemRights
- A link to the statement of rights (such as a Creative Commons or old-school copyright license) that govern the use of the document.
- MDItemSecurityMethod
- Encryption method used on the document.
- MDItemStarRating
- Rating of the document (as in the iTunes "star" rating).
- MDItemStateOrProvince
- The document's state or province of origin.
- MDItemTitle
- The title.
- MDItemVersion
- The version number.
- MDItemWhereFroms
- Where the document came from, such as a URI or email address.
Appendix B: Finding Long Songs
Here's a little Perl program to find songs longer than a certain number of minutes, and report on them in a friendly format, in reverse order of length. It uses mdfind to get a list of files for songs over a certain length, and then uses mdls to extract the details, and reports on its findings.
#!/usr/bin/perl -w
use warnings;
use strict;
# Get number of minutes from command line.
my $minutes = shift || 10; # default 10
my $seconds = $minutes * 60;
my @constraints = (
"kMDItemDurationSeconds > $seconds",
'kMDItemMediaTypes == "Sound"',
);
my $mdfind_args = join( " and ", @constraints );
my @filelist = `mdfind '$mdfind_args'`
or die "You don't have any songs over ",
"$minutes minutes long!\n";
chomp @filelist; # Remove trailing newlines
my @fileinfo; # List of matching files & stats
for my $filename ( @filelist ) {
my %fields;
# Call mdls on the file and scan each line
foreach ( qx{mdls "$filename"} ) {
# Find lines with key/value pairs
if ( /^kMDItem(\w+)\s+=\s+(.*)/ ) {
# Extract the keys and values
my ($key,$value) = ($1,$2);
# Strip surrounding parens & quotes
$value =~ s/^\(|\)$//g;
$value =~ s/^"|"$//g;
# Stash the key/value pair
$fields{$key} = $value;
}
} # for each mdls call
push( @fileinfo, \%fields );
}
# Sort in decreasing order of length
@fileinfo = sort {
$b->{DurationSeconds}
<=>
$a->{DurationSeconds}
} @fileinfo;
# Print the specs for each song
for my $file ( @fileinfo ) {
printf( qq{%2d:%02d "%s" by %s from "%s"\n},
$file->{DurationSeconds}/60,
$file->{DurationSeconds}%60,
$file->{Title},
$file->{Authors},
$file->{Album},
);
}
$ perl longsongs 9
20:34 "2112" by Rush from "2112"
18:36 "Alice's Restaurant Massacree" by Arlo
Guthrie from "The Best Of Arlo Guthrie"
...
9:16 "Between I And Thou" by The Mermen from
"A Glorious Lethal Euphoria"
9:05 "Watermelon In Easter Hay" by Frank Zappa
from "Joe's Garage"
9:03 "Slow Burn" by Silkworm from "Even A Blind
Chicken Finds A Kernel Of Corn Now And Then"
9:00 "The Load-Out / Stay" by Jackson Browne from
"Running On Empty"
Andy Lester is a QA & Release Manager for Socialtext. He is also in charge of PR for The Perl Foundation and maintains over 25 modules on CPAN.
Return to the Mac DevCenter
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 9 of 9.
-
perl script in Appendix B ("longsongs")
2006-01-14 13:24:29 movdpoel [Reply | View]
-
perl script in Appendix B ("longsongs")
2006-01-14 16:09:18 Andy Lester |
[Reply | View]
qq() is an alternate way of quoting strings in Perl. It acts like qq(string) is the same as "string", but is useful if the string you're quoting has quote characters in it, like ours does.
I don't know what other output you got, but I suspect the problem is that some of your tracks are missing author, title or album name fields.
-
perl script in Appendix B ("longsongs")
2006-01-15 08:57:51 movdpoel [Reply | View]
Yes, you are right. It is that simple (isn't it always?). A lot of my tracks don't have values in some fields. With the information you give in Appendix A, I can 'circumvent' that. Thanks for helping me back on track.
-
mdfind2
2006-01-05 18:09:06 schwa [Reply | View]
Forgive the self advertising - but you might also want to check out mdfind2 - a mdfind replacement that I wrote that outputs XML: http://toxicsoftware.com/blog/index.php/weblog/mdfind2/ -
mdfind2
2006-01-06 11:00:41 kwidholm [Reply | View]
That's a nice program, but too bad you decrease its usefulness and adaptability by making it a standalone replacement for mdfind instead of something that you can pipe mdfind into. Why not follow the flexibility and power of the command line tradition by making your program usable like this:
mdfind "search terms" | mdxml > found_items.xml
Assuming you would then change the name of your program to mdxml.
You don't have to worry about making and maintaining an interface to mdfind functionality, and users can do so much more with your tool.
-
mdfind2
2006-01-07 22:42:12 schwa [Reply | View]
What you're suggesting is a mdls command that takes a --xml switch. You could then use something like:
mdfind -0 'foo' | xargs -o mdls --xml
Unfortunately mdls doesn't take a --xml switch. So I'd have to write a "mdls2" command and I bet someone would complain that "too bad you decrease its usefulness and adaptability by making it a standalone replacement for mdfind".
Of course if you truly wished to harness the "flexibility and power of the command line tradition" then you could take the output of mdfind, pipe it through xargs and mdls and then through some awful sed/awk/perl abomination to convert the output of mdls into xml... I'm sure it would be extremely graceful, easy to use and easy to maintain...
-
some more examples
2006-01-04 19:01:58 hayne [Reply | View]
Here's a couple of Bash functions that illustrate a few more features of 'mdfind':
# locatemd: to search for a file using Spotlight's metadata
function locatemd { mdfind "kMDItemDisplayName == '$@'wc"; }
# locaterecent: to search for files created since yesterday using Spotlight
# This is an illustration of using $time in a query
# See: http://developer.apple.com/documentation/Carbon/Conceptual/SpotlightQuery/index.html
function locaterecent { mdfind 'kMDItemFSCreationDate >= $time.yesterday'; }
-
Great stuff
2006-01-04 18:51:39 mnystedt [Reply | View]
Thanks a bunch for this piece, I really appreciate it. Spotlight is a great technology but a GUI just isn't the best way of using it most of the time ;-) -
Great stuff
2006-01-04 19:59:55 Andy Lester |
[Reply | View]
Thanks, I'm glad you liked it. When I discovered mdfind as I was updating the book, my first thought was "Look at all the fun stuff I'll be able to do from the command line", and the second was "I bet most people won't know this exists, and I should tell them."
Scratching two itches with one article... :-)






The perl script gives me:
"Use of uninitialized value in printf at longsongs line 52".
I am not familiar with perl, to my untrained eye it seems the "qq" in printf is causing the mayhem. I would love to get it working
Great article by the way! mfind is very powerful and thanks for sharing that with us.