Running BSD's metadata tool in Terminal on a CSV file ($ mdls foo.csv
) will produce output like this:
kMDItemContentCreationDate = 2014-08-27 15:28:16 +0000
kMDItemContentModificationDate = 2014-08-27 15:28:16 +0000
kMDItemContentType = "public.comma-separated-values-text"
kMDItemContentTypeTree = (
"public.comma-separated-values-text",
"public.delimited-values-text",
"public.text",
"public.data",
"public.item",
"public.content"
)
kMDItemDateAdded = 2014-08-27 15:28:16 +0000
kMDItemDisplayName = "foo.csv"
kMDItemFSContentChangeDate = 2014-08-27 15:28:16 +0000
kMDItemFSCreationDate = 2014-08-27 15:28:16 +0000
kMDItemFSCreatorCode = ""
kMDItemFSFinderFlags = 0
kMDItemFSHasCustomIcon = (null)
kMDItemFSInvisible = 0
kMDItemFSIsExtensionHidden = 0
kMDItemFSIsStationery = (null)
kMDItemFSLabel = 0
kMDItemFSName = "foo.csv"
kMDItemFSNodeCount = (null)
kMDItemFSOwnerGroupID = 20
kMDItemFSOwnerUserID = 501
kMDItemFSSize = 962
kMDItemFSTypeCode = ""
kMDItemKind = "comma-separated values"
kMDItemLogicalSize = 962
kMDItemPhysicalSize = 4096
I would like to capture this output in code and convert it to a NSDictionary.
...
//
// run mdls on file
//
NSURL *url = @"path/to/file/foo.csv";
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;
NSTask *task = [[NSTask alloc] init];
task.launchPath = @"/usr/bin/mdls";
task.arguments = @[url];
task.standardOutput = pipe;
[task launch];
NSData *data = [file readDataToEndOfFile];
NSString *content = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
//
// populate dictionary
//
NSDictionary *dictionary = [NSDictionary alloc] init];
// pseudo-code
NSArray *rows = split string on \n to create array of rows;
for each row {
if (row doesn't end with a '(' or start with a ')') {
split rows on \= to create key and value;
add key and value to dictionary;
}
else if (row starts with a '(') {
add key to dictionary;
create NSArray;
set marker on;
}
else if (row ends with a ')') {
add value to dictionary;
set marker off;
}
if (marker) {
add value to array;
}
}
//
Is there a more-elegant approach?
Is there a more-elegant approach?
Boy, is there ever! ;)
Why are you trying to parse the output of the mdls
command when that command is built on APIs you can use yourself?
MDItemRef item = MDItemCreateWithURL(NULL, (__bridge CFURLRef)url);
CFArrayRef names = MDItemCopyAttributeNames(item);
NSDictionary* dictionary = CFBridgingRelease(MDItemCopyAttributes(item, names));
CFRelease(names);
CFRelease(item);
(And, just because you asked about parsing the output of mdls
, I'll point out that it has a -plist
option. If you use it and specify -
as the file, you can read a plist from its stdout and parse it using NSPropertyListSerialization
.)