bash, output groups one per line, with group name and group ID

  • A+
Category:Languages

Here is the information about the groups to which I belong, from the id command. I've made it so the output would be easier to read. I'm including this output "exactly" as it came back from the command line. (Thanks @EdMorton.)

$id uid=1(me) gid=545(Users) groups=545(Users),66049(CONSOLE LOGON),11(Authenticated Users),4095(CurrentSession),66048(LOCAL) 

Here is the output I want, comma delimited, with one group name and its GID per line:

$ some-great-command 'Users',545 'CONSOLE LOGON',66049 'Authenticated Users',11 'CurrentSession',4095 'LOCAL',66048 

I came up with a horrendous way to do this:

$ id | sed 's//(.*groups=/)/(.*$/)//2/' | awk -F "," '{ for(i = 1; i <= NF; i++) print $i;}' | sed 's//(^[[:digit:]]/+/)[(]/([A-Za-z +_]/+/)[)]$/'"'"'/2'"'"',/1/' 

(I'll put it here again with a little nicer on-screen format, using /)

$ id | sed 's//(.*groups=/)/(.*$/)//2/' | / awk -F "," '{ for(i = 1; i <= NF; i++) print $i;}' | / sed 's//(^[[:digit:]]/+/)[(]/([A-Za-z +_]/+/)[)]$/'"'"'/2'"'"',/1/' 

but I can't help but think there must be a better (or at least shorter and more elegant) way to accomplish this process. Can anyone share such a solution?

Note: One reason I'm doing this is that, sometimes, getent group GID is a bit finicky where I work. I've looked at some other posts, e.g. this one, but it didn't have the answer I wanted.

A nicer-to-read version of the id output which IS NOT THE SAME AS WHAT THE CONSOLE GAVE! There are newline characters after (Users) (note the space after the right paren) and after (LOCAL), (no space after the comma).

$ id uid=1(me) gid=545(Users)  groups=545(Users),66049(CONSOLE LOGON), 11(Authenticated Users),4095(CurrentSession),66048(LOCAL) 

Real id output:

$ id uid=1(me) gid=545(Users) groups=545(Users),66049(CONSOLE LOGON),11(Authenticated Users),4095(CurrentSession),66048(LOCAL) 


And there comes perl:

$ id | perl -pe "s/.*=/,/;s/,(/d+)/(([^)]+)/)/'/2',/1/n/g"                                                                  'arobert',1000 'adm',4 'cdrom',24 'sudo',27 'dip',30 'plugdev',46 'lpadmin',113 'sambashare',128 

Explanations:

Two find and replace commands will be executed:

  • s/.*groups=/,/ is used to remove everything before the groups definition
  • s/,(/d+)/(([^)]+)/)/'/2',/1/n/g will put in place the following actions detailed @demo

It would be difficult to write something shorter than this. Also if you are already good with sed and regex, than perl can be a nice plus to add to your list of skills.

As mentioned by Ed Morton, the current perl command generates an extra EOL at the end of the output. If you want to remove it you can use the following enhanced perl command:

$ id | perl -pe "s/.*=/,/;s/,(/d+)/(([^)]+)/)/'/2',/1/n/g;s//n/n//n/" 

Thanks Ed!!!

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: