Posted on 10-02-2022 10:48 PM
Hey Nation :-)
So here's a challenge for the scripting guru's...
I'm trying to write an EA for getting the Design Capacity for a built-in Intel MacBook Pro battery.
So far I have this script:
/usr/sbin/ioreg -r -c "AppleSmartBattery" | /usr/bin/grep -w "DesignCapacity" | /usr/bin/awk '{print $3}'
But this yields me waaaaaay too much info and the required awk value is on it's own new line right at the bottom.
The body of the result output does contain the "DesignCapacity" value mixed in among hundreds of other values!
So my challenge is... how do I get rid of all that extra value output to just have the final line output?
eg:
me@MacBookPro ~ % /usr/sbin/ioreg -r -c "AppleSmartBattery" | /usr/bin/grep -w "DesignCapacity" | /usr/bin/awk '{print $3}'
gives this result:
{"PMUConfigured"=0,"FccComp2"=5050,"ResScale"=133,"SystemPower"=1051098690,"Qmax"=(5496,5497,5510),"DesignCapacity"=5103,"CellVoltage"=(4169,4169,4169),"PassedCharge"=26,"RaTableRaw"=(<00550070005f007300780084006c0074007c007f0082007a009000da0179024e>,<000000650055006100660072005d0065006c007100760072008800ca0168022f>,<0000006c005c006e0073007e0067006e00760079007c0074008a00d20173023e>),"StateOfCharge"=88,"PresentDOD"=(12,12,12),"Flags"=557318657,"DataFlashWriteCount"=3462,"DOD0"=(2080,2096,2080),"ChemID"=9216,"AdapterPower"=0,"CycleCount"=9,"Voltage"=12511,"GaugeFlagRaw"=192,"FccComp1"=5168,"BatteryState"=<000000000000000043e4000202000000>,"ManufactureDate"=52987870328882,"LifetimeData"={"TotalOperatingTime"=14205,"UpdateTime"=1664774348,"AverageTemperature"=0,"TimeAtHighSoc"=<58000000cb0100000300000000000000>},"Serial"="F5D01130MLSKGGJBB"}
5103
me@MacBookPro ~ %
(the number "5103" is the value I am after...)
Thanks y'awl for any help and comments - but be gentle... it's my first post! :-)
Solved! Go to Solution.
Posted on 10-03-2022 09:54 AM
There's probably a way to consolidate the two cut commands at the end of this, but it has worked for me:
/usr/sbin/ioreg -i -w 0 -f -r -c AppleSmartBattery | /usr/bin/grep "BatteryData" | /usr/bin/grep -o 'DesignCapacity.*' | /usr/bin/cut -f2- -d"=" | /usr/bin/cut -f1 -d","
10-03-2022 01:59 PM - edited 10-18-2022 01:56 PM
@bkruger @dwbergstrom Please just learn to correctly use the ioreg options. Parsing is built-in to the ioreg binary. The reason you should do this instead of awk / grep / sed is that system values may change & your sketchy parsing may stop working. If you actually use the structure in the data provided by something like ioreg your EAs will probably have a longer shelf life.
In the ioreg command posted above the -w 0 makes absolutely no difference. Limiting the width is unneeded & is not meant for parsing, only for reading.
The only line in the output changed by the "smart formatting" -f flag is the "manufacture data" key / val which you aren't using. Totally useless.
The inheritance flag -i is, again, totally useless as all it is doing is showing class names above the object at the top of the output.
So, what you are left with that is actually meaningful is the following:
/usr/sbin/ioreg -r -c AppleSmartBattery
This obtains the "root" (-r) of the "class" (-c) AppleSmartBattery.
To use PlistBuddy to get the key/val you want in the data ("BatteryData") use the -a option for "archive" format:
% /usr/libexec/PlistBuddy -c "print 0:BatteryData:DesignCapacity" /dev/stdin <<< "$(/usr/sbin/ioreg -ar -c AppleSmartBattery)"
5103
Posted on 10-03-2022 09:54 AM
There's probably a way to consolidate the two cut commands at the end of this, but it has worked for me:
/usr/sbin/ioreg -i -w 0 -f -r -c AppleSmartBattery | /usr/bin/grep "BatteryData" | /usr/bin/grep -o 'DesignCapacity.*' | /usr/bin/cut -f2- -d"=" | /usr/bin/cut -f1 -d","
Posted on 10-03-2022 01:19 PM
dwbergstom!! You are da man!
Kudos - never thought to use the cut command! Here I was messing about with sed... :-)
But thank you very much - the bonus is that it also works with Apple Silicon too!
(and the battery output from Silicon MacBooks has 10x more values!)
Thank You again.
Jamf Nation and Jamf Community Rocks. √
Posted on 10-03-2022 01:34 PM
Sure thing! I had the scenario of needing this to work on both Apple Silicon and Intel, so this is what ended up working out. Glad it's helpful!
10-03-2022 01:59 PM - edited 10-18-2022 01:56 PM
@bkruger @dwbergstrom Please just learn to correctly use the ioreg options. Parsing is built-in to the ioreg binary. The reason you should do this instead of awk / grep / sed is that system values may change & your sketchy parsing may stop working. If you actually use the structure in the data provided by something like ioreg your EAs will probably have a longer shelf life.
In the ioreg command posted above the -w 0 makes absolutely no difference. Limiting the width is unneeded & is not meant for parsing, only for reading.
The only line in the output changed by the "smart formatting" -f flag is the "manufacture data" key / val which you aren't using. Totally useless.
The inheritance flag -i is, again, totally useless as all it is doing is showing class names above the object at the top of the output.
So, what you are left with that is actually meaningful is the following:
/usr/sbin/ioreg -r -c AppleSmartBattery
This obtains the "root" (-r) of the "class" (-c) AppleSmartBattery.
To use PlistBuddy to get the key/val you want in the data ("BatteryData") use the -a option for "archive" format:
% /usr/libexec/PlistBuddy -c "print 0:BatteryData:DesignCapacity" /dev/stdin <<< "$(/usr/sbin/ioreg -ar -c AppleSmartBattery)"
5103
Posted on 10-05-2022 04:44 PM
@brockwalters - you are also da man!
It's so good to get such helpful and very specific guidance on this forum. Jamf Nation! I'm a fan!
I think firstly I have to say thank you to @dwbergstrom for exactly answering my OP and question - he did indeed give me the correct syntax that I was looking for to sort through the std output.
And then I have to give extra thanks to @brockwalters for some very good advice and guidelines on setting up EA and future-proofing them! It's a great approach to check the plist file and use the key values instead!!
So in the end, not just did I get my original script working, but I was also schooled in a better way to get it (and future EA's) working... Thank you both guys
11-15-2022 05:17 PM - edited 11-15-2022 05:30 PM
And if you have homebrew and GNU sed handy:
/usr/sbin/ioreg -i -w 0 -f -r -c AppleSmartBattery|gsed -nE '/BatteryData/{s/^.+DesignCapacity.=//;s/,.*$//p } '
For some reason the OS/X sed doesn't like the curly braces, even though the manual claims that they work for grouping =/
And w/o foreign help:
/usr/sbin/ioreg -i -w 0 -f -r -c AppleSmartBattery|/usr/bin/awk '/BatteryData/{sub(/^.+DesignCapacity"=/,"");sub(/,.+$/,"");print}'
11-21-2022 03:22 PM - edited 11-21-2022 03:24 PM
@Tinkster Again, why? The output of ioreg with -a is a plist. On macOS, that's a native format which you can parse with PlistBuddy. Why do you think offering a way to do this that isn't native & that requires a GNU version of a binary that isn't native is somehow equivalent or better? It's not. Why do you think using awk is better? It's not. PlistBuddy lets you use the semi-structured data to get right to the key / value you need.
Posted on 11-21-2022 04:45 PM
The `awk` used above comes w/ the OS, it's not the GNU version.
Plistbuddy doesn't.
Why shouldn't I be using what I have ready available?
11-21-2022 06:56 PM - edited 11-22-2022 04:31 PM
@Tinkster
PlistBuddy is part of macOS... /usr/libexec/PlistBuddy
gsed is not native nor did I say awk wasn't native. Reading for comprehension is a powerful skill...
As for your question: parsing semi-structured data using key/value pairs is always better & more precise & more future proof than bash %*@&ery. That’s why.