How can I remove unnecessary text from a command line output?

2

1

I'm using GeekTool, which takes the output of terminal commands and turns them into Desktop widgets, and wanted to display the current battery percent of my bluetooth keyboard to the Desktop in the form of

Keyboard Battery: (Battery percent value)

In order to accomplish this, I am using the command

ioreg -c AppleBluetoothHIDKeyboard |grep '"BatteryPercent" ='

which is from this website.

However, as mentioned on that website, this command outputs this not-very-clean-looking text (yes I need to change my batteries):

| |   |   |   "BatteryPercent" = 17

(So, for this input, I want the output Keyboard Battery: 17.)  Therefore, my question is, how do I convert this into my intended format of "Keyboard Battery: (Battery percent value)" via the command line?

EDIT: I have found another way to show the battery percent, using Ubersicht instead of GeekTool, thank you all for your help

D4rKP01s0n

Posted 2016-07-01T18:34:45.907

Reputation: 23

So, do you want Keyboard Battery: 17 or Keyboard Battery: (17)? I.e., do you want literal parentheses in the output? – G-Man Says 'Reinstate Monica' – 2016-07-01T20:23:40.397

Keyboard Battery: 17 – D4rKP01s0n – 2016-07-01T20:28:59.940

Please don’t clarify your question in comments; [edit] your question to make it clearer and more complete.  Several of us have put some effort into answering your question.  If you don’t want an answer any more, say so and walk away, and we’ll leave you alone.  But if you want a solution, copy our answers *into your question* and show the output you get *in your question*.  Use copy & paste from our answers to your Terminal, and from your Terminal to your question. – G-Man Says 'Reinstate Monica' – 2016-07-02T22:40:14.360

Answers

0

Please read, understand, and acknowledge this question:

Does the ioreg -c AppleBluetoothHIDKeyboard command output only that one line, or does it also output other lines (that contain numbers)?


Since you want the output Keyboard Battery: 17, which neither of the answers posted so far will produce, you can

Build on jehad’s answer:

If the ioreg command outputs only the BatteryPercent line, then

echo "Keyboard Battery: $(ioreg -c AppleBluetoothHIDKeyboard | grep -oE '[0-9]+')"

But if, as I suspect, the ioreg -c AppleBluetoothHIDKeyboard command outputs other lines (that contain numbers), in addition to the "BatteryPercent" = line, then the above command will also output many other lines with numbers.

If, as you have implicitly confirmed, the ioreg command outputs other lines (that contain numbers), then

echo "Keyboard Battery: $(ioreg -c AppleBluetoothHIDKeyboard | grep BatteryPercent | grep -oE '[0-9]+')"

jehad’s revised answer might work if the ioreg command outputs only the BatteryPercent line, although it may require small changes.

Build on Buffalo Rabor’s answer:

Buffalo Rabor’s revised answer will work, with the proviso that it includes explicit parentheses in the output.  But it can be simplified — you hardly ever need to pipe grep into awk:

ioreg -c AppleBluetoothHIDKeyboard | awk '/BatteryPercent/ {print "Keyboard Battery: "$7}'

P.S.

I don’t have a Mac either, so I can’t be sure what will work for you and what won’t.

G-Man Says 'Reinstate Monica'

Posted 2016-07-01T18:34:45.907

Reputation: 6 509

echo "Keyboard Battery: $(ioreg -c AppleBluetoothHIDKeyboard | grep -oE '[0-9]+')" outputs many other lines with numbers, as does the second and third commands that you have provided. In addition, both Buffalo's and jehad's answers do not work, with jehad's revision resulting in sed: 1: "s/."([[:digit:]])".*/ ...": \1 not defined in the RE and Buffalo's second option, while it was outputting different earlier, now outputs ='|awk '{print $5, $6, $7}' "BatteryPercent" = 51 awk: can't open file BatteryPercent source line number 1 – D4rKP01s0n – 2016-07-02T21:51:52.093

As I and @G-Man have warned, we do not have Mac. And we can only test on our GNU sed, which is almost certainly not the same as in Mac OS. If you experiment, I'm sure you can get a variation of one of our solutions to work. For example, "\1 not defined" error could mean that you need to use '' before the brackets, so the part ([[:digit:]]*) becomes \([[:digit:]]*\). – jehad – 2016-07-02T22:10:11.783

@D4rKP01s0n: It would be unusual for a command to work one day and fail explosively the next day, unless catastrophic changes have been made to the system in the interim.  It is more likely that you have made a typing error.  In particular, if you are getting an error message that begins with ='|awk, you have probably mistyped the quotes. – G-Man Says 'Reinstate Monica' – 2016-07-02T22:39:11.290

1

To get just the number, change the "grep" in your example to the following:

grep -oE '[0-9]+'

This should work (at least the grep syntax will certainly work on Linux), but I don't have a Mac, so you may need to tweak it a little to get it to work.

Explanation:

  • The above grep is extracting just the number part of the output.
  • 'o' option says show ONLY the match.
  • 'E' option says use regular expression for matching.
  • '[0-9]+' is the regular expression to find numbers (+ means one or more).

Therefore, this grep command will find just the number part of the output string.

..

EDITED... after a second reading, seems like you need the number appended to the end of "Keyboard Battery:", so here is a solution using sed:

ioreg -c AppleBluetoothHIDKeyboard | sed -r 's/.*=[[:space:]]*([[:digit:]]*).*/Keyboard Battery: \1/;'

In this case, you're replacing the original string with one that begins with "Keyboard Battery: ".

Again, hope it works on Mac!

jehad

Posted 2016-07-01T18:34:45.907

Reputation: 1 376

Ok thanks, I'll try this out on my Mac when I get back to it and will mark this as the answer if it works – D4rKP01s0n – 2016-07-01T19:25:47.390

You might want to change that to sed 's/.* \([0-9][0-9]*\).*/Keyboard Battery: \1/'. – G-Man Says 'Reinstate Monica' – 2016-07-01T20:38:10.117

@G-Man why would you need two classes of digit? The same effect can be had with the plus (one or more) operator; [0-9]+, or you can use an even more short-hand \d+. In my experience the more verbose [[:digit:]] class is more widely supported (like I say, don't have a Mac, so wanted something more likely to work). The reason for [[:digit:]]* in my answer (instead of [[:digit:]]+) is because I don't know the possible output of ioreg, so best to have a match than no match (no match would return just the original string). – jehad – 2016-07-01T22:34:56.423

@jehad: I use  RERE *  because my version of sed doesn’t recognize +.  Also, it doesn’t recognize \d.  A problem with  RE *  is that it can match a null string.  I don’t understand why you prefer that to getting no match; if your [[:digit:]]* matches a null string, then your \1 is null, and you mangle the input line (possibly discarding a number somewhere else in the line).  Also, I find that sed treats ( and ) as non-special characters, and needs \(\) to capture a substring (→ \1).  … (Cont’d) – G-Man Says 'Reinstate Monica' – 2016-07-02T00:23:22.150

(Cont’d) … Your command is flawed in that (1) it expects the number in the input to be surrounded by quotes (it isn’t), (2) it inserts quotes into the replacement string (not desired), and (3) it inserts : into the replacement string twice. Also, the ; is unnecessary. – G-Man Says 'Reinstate Monica' – 2016-07-02T00:24:04.933

@G-Man Thanks for taking the time to check in detail. I've tested mine and it works as I expect and as I've described, and my experience of sed is contradictory to what you're telling me (I would disagree with your points, but no need)... hmm, this is getting interesting; there's stuff I can learn here. I'm currently using sed (GNU sed) 4.2.2, which is what comes packaged with Linux/Ubuntu 14.04. Could you please tell me what version of sed you use, I would like to try it out? – jehad – 2016-07-02T01:17:00.040

@G-Man, again thanks for checking, you've made me take a second look, and I noticed that I incorrectly assumed the number was enclosed in double quotes and that there was a requirement for double quotes on the output. So, I've edited my solution further. – jehad – 2016-07-02T22:29:06.217

@jehad: This is interesting. My sed (invoked with --version) *also* says sed (GNU sed) 4.2.2.  (I'm running it on Cygwin.) I wonder whether we have something significant different in our environments. – G-Man Says 'Reinstate Monica' – 2016-07-02T22:47:04.473

I've learned my lesson. "I must leave well alone any questions involving Mac, when I have no Mac". :-) However our environments differ, we seem to be causing more trouble for the poor original-poster. – jehad – 2016-07-02T22:53:12.693

1

pipe to awk...

$ioreg -c AppleBluetoothHIDKeyboard |grep '"BatteryPercent" ='|awk '{print $5, $6, $7}'
"BatteryPercent" = 51

or

$ioreg -c AppleBluetoothHIDKeyboard |grep '"BatteryPercent" ='|awk '{print "Keyboard Battery: ("$7")"}'
Keyboard Battery: (51)

Buffalo Rabor

Posted 2016-07-01T18:34:45.907

Reputation: 11