2

I need to create a list of all installed applications in .csv format. The Mac System Information report is great, but I cannot find a way to convert the .spx file it generates to .csv which is more useful for my needs.

My goal is to generate a list of installed applications.

I like the System Information because it gives me useful data such as the last modified date, application kind (Universal, Intel).

Are there ways to do this data collection to a csv formatted text file?

1
  • Doesn't look like a big deal, it's just an XML file. Commented Aug 18 at 2:54

1 Answer 1

2

With enough scripting, you could surely extract the data from the XML dump, but System Profiler has a command line flag that makes it output JSON, which is much more convenient to work with:

system_profiler -json -nospawn SPApplicationsDataType -detailLevel full

And it's a bit hacky, but Apple's "Open Scripting Architecture" command line tool osascript supports JavaScript, so it can be abused to parse and manipulate JSON without installing any third-party tools. Here's the JavaScript that converts the JSON dump to CSV:

let apps = /* [system_profiler output] */.SPApplicationsDataType;
// Collect all keys present in any row
let keys = apps.reduce((keys, app) =>
{
    for(let k of Object.keys(app))
        if(keys.indexOf(k) == -1)
            keys.push(k);
    return keys;
}, []);
// Extract values and replace missing values with empty string
let csv = apps.map(app => keys.map(k => app[k] || ''));
// Add keys as column headers
csv.unshift(keys);
// Yield the output (implicitly printed in osascript)
csv.map(row => row.map(field =>
{
    // Turn all entries into strings
    let s = field + '';
    // Escape lines with commas, quotes and newlines
    return s.match(/[,"\n]/) ? '"' + s.replace('"', '""') + '"' : s;
}).join(',')).join('\n')

Now we just replace /* [system_profiler output] */ with $(cat /dev/stdin), put backslashes in front of double quotes and other backslashes, cram it all into a shell string, chain the two commands together and we have a one-liner that outputs CSV:

system_profiler -json -nospawn SPApplicationsDataType -detailLevel full | osascript -l JavaScript <<<"let apps = $(cat /dev/stdin).SPApplicationsDataType; let keys = apps.reduce((keys, app) => { for(let k of Object.keys(app)) if(keys.indexOf(k) == -1) keys.push(k); return keys; }, []); let csv = apps.map(app => keys.map(k => app[k] || '')); csv.unshift(keys); csv.map(row => row.map(field => { let s = field + ''; return s.match(/[,\"\\n]/) ? '\"' + s.replace('\"', '\"\"') + '\"' : s; }).join(',')).join('\n')"

Can be piped to a file by appending something like >~/Desktop/dump.csv.

1
  • Thank you @Siguza - Incredibly helpful response !!!
    – mlondon
    Commented Aug 19 at 18:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .