how to display users under a group in a line for each user in Linux bash
Asked Answered
T

6

7

Currently when I run a grep command on a visitors group that I had created

grep visitors:x:1011: /etc/group

This is a sample result of the above command, as the actual result is too long.

visitors:x:1011:ellipsiscoterie,magnetcommonest,wizardmeans,beakskeletal,lemonwellmade,ralphpaperclips etc..

How do I display the above result as shown below (without visitors:x:1101 and separating the commas), as I have difficulty doing so.

ellipsiscoterie
magnetcommonest
wizardmeans
beakskeletal
lemonwellmade
ralphpaperclips
Tune answered 19/10, 2021 at 5:35 Comment(0)
S
9

I suggest using sed instead of grep

sed -n -e 's/^visitors\:x\:1011\://p' /etc/group | tr ',' '\n'

UPD: detailed explain of sed part is here. tr examples you can find here

Sphalerite answered 19/10, 2021 at 5:45 Comment(0)
C
4

Using awk, you can set the field separated to a colon using -F: and check if the string starts with visitors:x:1011:

As the comma separated values always seems to be at the end, split the last field $NF on a comma and loop the splitted values.

awk -F: '
/^visitors:x:1011:/ {
  count=split($NF, ary, ",");
  for(i=1; i<=count; i++) print ary[i];
}' /etc/group
Confiscate answered 19/10, 2021 at 6:51 Comment(0)
D
3

A good approach to query groups and users is making use of the getent command as it also works on ldap systems.

$ getent group visitors | cut -d: -f4 | tr ',' '\n'

On standard systems this will always work as usernames and groupnames cannot contain the <comma>-character or the <colon>-character. (If you have a non-standard Linux or Unix system, see man useradd and man groupadd to check the username and group name rules)

If you want to use awk instead of this little pipeline, then an elegant—but cryptic—version would read:

$ getent group visitors | awk -F: '{FS=",";OFS=ORS;$0=$4;$1=$1}1'
Davidson answered 19/10, 2021 at 7:5 Comment(3)
I wish I had thought of getent when I wrote my answer. I'd still use awk to parse the output though, but still, getent seems like the appropriate tool for this.Footless
@TedLyngmo I'm also a big fan of awk, however one should not underestimate the efficiency of piping and those optimized atomic tools that can do one thing very well (cut, paste, tr, join, ...). awk is a bit of a sledgehammer for a task like thisDavidson
:-) True. It's not the tools. It's the extra process and pipe I'd like to avoid, but in reality, it probably won't matter much. I really like your awk version! Wish I could upvote it one more time.Footless
H
3

With your shown samples please try following awk program.

awk -F':' '/^visitors:x:1011/ && NF==4{gsub(/,/,ORS,$4);print $4}' /etc/group

OR in case entry visitors:x:1011 comes only once in your file then try following:

awk -F':' '/^visitors:x:1011/ && NF==4{gsub(/,/,ORS,$4);print $4;exit}' /etc/group

Explanation: Simple explanation would be, making field separator as : for all lines. Then in main program, checking condition if line starts from visitors:x:1011 and number of fields are 4 then globally substitute comma with new line(ORS) in 4th field and print it.



OR if line with visitors:x:1011 comes once and 4th field is NULL(means no entry present which is obvious in some cases) and you want to print message for it then try following:

awk -F':' '/^visitors:x:1011/ && NF==4{if($4==""){print "NO entry found in /etc/group"} else{gsub(/,/,ORS,$4);print $4};exit}' /etc/group

Harlow answered 19/10, 2021 at 7:10 Comment(0)
F
1

One option could be to use awk:

awk -F: '$1 == "visitors" {
    size = split($4, users, ",");
    for(i=1; i<=size; ++i) print users[i];
    exit }' /etc/group
  • -F: - Use : as the field separator
  • $1 == "visitors" - If the first field matches visitors execute the following statement (within { ... })
  • size = split($4, users, ","); - Split the 4:th field on , and store the result in the array users. Returns the number of elements in users and puts that in size.
  • The for loop - Loop over all the elements in users and print them out.
  • exit - Terminate awk - There's no need to continue reading the rest of the file.
Footless answered 19/10, 2021 at 6:0 Comment(0)
L
0

If the result of grep visitors:x:1011: /etc/group is a text line:

visitors:x:1011:ellipsiscoterie,magnetcommonest,wizardmeans,beakskeletal,lemonwellmade,ralphpaperclips

you could try this awk:

awk '/^visitors:/ {sub(/([^:]+:)+/,"");gsub(/,/, ORS)} 1' file
ellipsiscoterie
magnetcommonest
wizardmeans
beakskeletal
lemonwellmade
ralphpaperclips
  • initial regexp: if the line matches visitors: at the beginning, do the following.
  • the action: eliminate all characters till last : using sub() and then substitute, using gsub(), all commas by the default value of ORS.
Legendre answered 19/10, 2021 at 8:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.