3.7 C
New York
Saturday, November 30, 2024

macos – The right way to convert Mac System Info report in .spx to .csv?


With sufficient scripting, you could possibly absolutely extract the info from the XML dump, however System Profiler has a command line flag that makes it output JSON, which is rather more handy to work with:

system_profiler -json -nospawn SPApplicationsDataType -detailLevel full

And it is a bit hacky, however Apple’s “Open Scripting Structure” command line device osascript helps JavaScript, so it may be abused to parse and manipulate JSON with out putting in any third-party instruments. This is the JavaScript that converts the JSON dump to CSV:

let apps = /* [system_profiler output] */.SPApplicationsDataType;
// Gather all keys current in any row
let keys = apps.scale back((keys, app) =>
{
    for(let ok of Object.keys(app))
        if(keys.indexOf(ok) == -1)
            keys.push(ok);
    return keys;
}, []);
// Extract values and change lacking values with empty string
let csv = apps.map(app => keys.map(ok => app[k] || ''));
// Add keys as column headers
csv.unshift(keys);
// Yield the output (implicitly printed in osascript)
csv.map(row => row.map(discipline =>
{
    // Flip all entries into strings
    let s = discipline + '';
    // Escape traces with commas, quotes and newlines
    return s.match(/[,"n]/) ? '"' + s.change('"', '""') + '"' : s;
}).be part of(',')).be part of('n')

Now we simply change /* [system_profiler output] */ with $(cat /dev/stdin), put backslashes in entrance of double quotes and different backslashes, cram all of it right into a shell string, chain the 2 instructions collectively and we’ve 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.scale back((keys, app) => { for(let ok of Object.keys(app)) if(keys.indexOf(ok) == -1) keys.push(ok); return keys; }, []); let csv = apps.map(app => keys.map(ok => app[k] || '')); csv.unshift(keys); csv.map(row => row.map(discipline => { let s = discipline + ''; return s.match(/[,"n]/) ? '"' + s.change('"', '""') + '"' : s; }).be part of(',')).be part of('n')"

Could be piped to a file by appending one thing like >~/Desktop/dump.csv.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles