Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Output groups one per line, with group name and group ID

Tags:

regex

bash

sed

awk

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)
like image 696
bballdave025 Avatar asked May 17 '18 01:05

bballdave025


People also ask

How can I get group name from gid?

You can lookup a group by name or gid using the getent command.

How do you display the gid of a group in Linux?

In Linux, how do I find a user's UID or GID? To find a user's UID (user ID) or GID (group ID) and other information in Linux/Unix-like operating systems, use the id command. This command is useful to find out the following information: Get User name and real user ID.

How do I find my group ID in Ubuntu?

Open the Ubuntu Terminal through Ctrl+Alt+T or through the Dash or connect to the Ubuntu system by SSH. This command lists all the groups that you belong to. You can also use the following command to list the group members and their GIDs. The gid output represents the primary group assigned to a user.


3 Answers

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!!!

like image 89
Allan Avatar answered Nov 15 '22 05:11

Allan


awk -v RS=, -F'[()=]' '{print "\047"$(NF-1)"\047,"$(NF-2)}'

e.g. given this input data:

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

and using cat file in place of id:

$ cat file | awk -v RS=, -F'[()=]' '{print "\047"$(NF-1)"\047,"$(NF-2)}'
'Users',545
'CONSOLE LOGON',66049
'Authenticated Users',11
'CurrentSession',4095
'LOCAL',66048
like image 42
Ed Morton Avatar answered Nov 15 '22 07:11

Ed Morton


Following awk may help you on same.

awk -v s1="'" -F"[)(=,]"  '/uid/{print s1 $(NF-1) s1 OFS $(NF-2);next} /groups/{print s1 $6 s1 OFS s1 $5 s1 ORS s1 $(NF-2) s1 OFS $(NF-3);next} /CurrentSession/{print s1 $2 s1 OFS $1 ORS s1 $(NF-1) s1  OFS $(NF-2)}' OFS=,  Input_file

OR

id | awk -v s1="'" -F"[)(=,]"  '/uid/{print s1 $(NF-1) s1 OFS $(NF-2);next} /groups/{print s1 $6 s1 OFS s1 $5 s1 ORS s1 $(NF-2) s1 OFS $(NF-3);next} /CurrentSession/{print s1 $2 s1 OFS $1 ORS s1 $(NF-1) s1  OFS $(NF-2)}' OFS=, 

Adding a non-one liner form of solution too now.

awk -v s1="'" -F"[)(=,]"  '
/uid/                    {  print s1 $(NF-1) s1 OFS $(NF-2);                          next}
/groups/                 {  print s1 $6 s1 OFS s1 $5 s1 ORS s1 $(NF-2) s1 OFS $(NF-3);next}
/CurrentSession/         {  print s1 $2 s1 OFS $1 ORS s1 $(NF-1) s1  OFS $(NF-2);         }
' OFS=,   Input_file

OR

id | awk -v s1="'" -F"[)(=,]"  '
/uid/                    {  print s1 $(NF-1) s1 OFS $(NF-2);                          next}
/groups/                 {  print s1 $6 s1 OFS s1 $5 s1 ORS s1 $(NF-2) s1 OFS $(NF-3);next}
/CurrentSession/         {  print s1 $2 s1 OFS $1 ORS s1 $(NF-1) s1  OFS $(NF-2);         }
' OFS=, 
like image 35
RavinderSingh13 Avatar answered Nov 15 '22 07:11

RavinderSingh13