How to list all users in an administrative group in linux - linux

i am using "getent passwd | cut -d : -f 1 | xargs groups > users.txt" but this lists all users and the groups they are in. In my case there are thousands of users I only need the list of users part of a specific group.
current output is in pic I don't need the members of linux_users group

Each record in /etc/group ends with a list of users that have that group as their supplementary group ( See http://linux.die.net/man/5/group ).
To get all members of your target group, you need to get those plus all users who have the target group as their primary group (in /etc/passwd, identified by your target group's number mentioned in /etc/group).
This script will get you both (you can call it group_ls or something like that):
#!/bin/sh
num_membs="$( getent group "$1" |cut -d: -f3,4 )"
num="${num_membs%:*}"; membs="${num_membs#*:}"
( IFS=,
printf '%s\n' $membs
awk -v num=$num -F: ' $4 == num { print $1 } ' /etc/passwd
) | sort -u
Alternatively, based on your approach
getent passwd | cut -d : -f 1 | xargs groups |
grep ":.* $1 .*" |cut -d : -f1
should do it too.

You can pipe to grep to narrow down the list that you get. Use some like grep groupname.
Grep: http://www.gnu.org/software/grep/manual/grep.html
Then you can use awk to only get part of a line.
Awk: http://tldp.org/LDP/abs/html/awk.html
So in your case you could do: getent passwd | cut -d : -f 1 | xargs groups | grep linux_admins | awk {'print $1'} > users.txt

You can also read the list of users associated with a group (example: users below) into an array in bash with the following:
IFS=$',\n' read -a names < <(grep '^users:' /etc/group | sed 's/^.*://')
Then you can access each user in a simple loop, e.g.
for i in ${names[#]}; do echo "$i"; done
This will only work for shells that support indexed arrays and process substitution, otherwise the pipe gymnastics are required.

Related

How to show all users in bash which does not end with "specific character"s

All the users in the system that dosen't have as an ending character on their names a, s, t, r, m, z must be shown in Bash.
The users names can be obtained from the /etc/passwd file, in the first column. But I can not perceive the correct approach to exclude those characters from the search.
Should I use grep? Or just a cut?
Something like
grep -o '^[^:]*[^astrmz:]:' /etc/passwd | tr -d :
or
cut -d: -f1 /etc/passwd | grep '[^astrmz]$'
[^blah] matches any character but the ones listed, the opposite of [blah].
GNU grep using a lookahead:
grep -Po '^[^:]*[^astrmz:](?=:)' /etc/passwd
Or using awk instead:
awk -F: '$1 ~ /[^astrmz]$/ { print $1 }' /etc/passwd
Or in pure bash without external commands:
while IFS=: read -r name rest; do
if [[ $name =~ [^astrmz]$ ]]; then
echo "$name"
fi
done < /etc/passwd
As you can see, there's lots of potential approaches.
Simple one liner when using bash:
compgen -u | grep -v '[astrmz]$'
The compgen -u command will produce a list of users (without all of the extra fields present in /etc/passwd); compgen is a builtin in bash where it's normally used for username completion.
This should do the trick:
cut -d: -f1 /etc/passwd | grep -vE 's$|t$|r$|m$|z$'
The cut command strips out the username from the password file.
Then grep -v (does the UNMATCHING)
grep -E does multiple matching (OR OR OR)
the $ sign indicates the last character to match
For example , on my mac, I get:
_gamecontrollerd
_ondemand
_wwwproxy
_findmydevice
_ctkd
_applepay
_hidd
_analyticsd
_fpsd
_timed
_reportmemoryexception
(You see no names end with those 5 letters).
Good Luck.

I need to grep for an exact word in password file but I get two responses back

I am using grep to parse the password file.
When I use
grep -w "avahi" /etc/passwd
I get two responses
avahi and avahi-autoipd
I have not found a method to give me the unique response.
This command is part of a bigger script where the name (avahi) is actually a variable.
This does work when the name is rpc and rpcuser. So I am guessing the it has something to do with the dash (-) in the name.
Actual code:
#!/bin/ksh
getent shadow |cut -d: -f1-2|grep ':!!'| cut -d: -f1 > /tmp/pasck
while read line
do
NOLOGIN=`grep -w $line /etc/passwd | cut -d -f7|cut -d/ -f3`
if [[ $NOLOGIN != "nologin: && $NOLOGIN != "false" ]] ; then
echo "$line" "$NOLOGIN" >> /tmp/pasck.list
fi
done <?tmp/pasck
The script is trying to go through the shadow file and look for users with no passwords. Then I compare the results to the passwd file to find which of those accounts are set to /bin/false or /sbin/nologin. The remainder would be actual users with no password set but allowed on the system.
Keeping things simple - you could include colon that comes after the username in your grep statement:
$ grep "^avahi:" /etc/passwd
You can use awk and explicitly test the first colon-separated field:
awk -F: '$1 = "avahi"' /etc/passwd

I need a grep command that will pull the usernames only from the /etc/passwd file in linux

I need a grep or another like command that will pull the usernames only from the /etc/passwd file in linux. Anything before the colon. I know this is doing with reg ex however I am not nearly experienced enough...
The following command will give all ACTUAL users, I need a way to pipe to grep or another line of code to only display the username portion.
awk -v LIMIT=500 -F: '{print $1}' '($3>=LIMIT) && ($3!=65534)' /etc/passwd
This should do:
awk -F: '$3>=LIMIT && $3!=65534 {print $1}' LIMIT=500 /etc/passwd
To do this in mostly plain bash:
limit=500
nfsnobody_id=65534
cut -d: -f1,3 /etc/passwd | while IFS=: read username uid; do
(( uid >= limit && uid != nfsnobody_id )) && echo $username
done
Get out of the habit of using VARNAMES_IN_CAPS: one day you'll write PATH=$(dirname $FILE) and then wonder why commands can no longer be found.
You simply need to rewrite the filter part of your awk command a bit. For instance, the following should work:
awk -v LIMIT=500 -F: '{if (($3>=LIMIT) && ($3!=65534)) print $1}' /etc/passwd
Otherwise, to answer your question strictly, if you want to use grep, the command would be
... | grep -o "^[^:]*"
but that would not be the way to go.

grepping using the result of previous grep

Is there a way to perform a grep based on the results of a previous grep, rather than just piping multiple greps into each other. For example, say I have the log file output below:
ID 1000 xyz occured
ID 1001 misc content
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content
ID 1001 misc content
To begin with, I'd like to grep the whole log file file to see if "xyz occured" is present. If it is, I'd like to get the ID number of that event and grep through all the lines in the file with that ID number looking for the status code.
I'd imagined that I could use xargs or something like that but I can't seem to get it work.
grep "xyz occured" file.log | awk '{ print $2 }' | xargs grep "status code" | awk '{print $NF}'
Any ideas on how to actually do this?
A general answer for grep-ing the grep-ed output:
grep 'patten1' *.txt | grep 'pattern2'
notice that the second grep is not pointing at a file.
More about cool grep stuff here
You're almost there. But while xargs can sometimes be used to do what you want (depending on how the next command takes its arguments), you aren't actually using it to grep for the ID you just extracted. What you need to do is take the output of the first grep (containing the ID code) and use that in the next grep's expression. Something like:
grep "^ID `grep 'xyz occured' file.log | awk '{print $2}'` status code" file.log
Obviously another option would be to write a script to do this in one pass, a-la Ed's suggestion.
Yet another way
for x in `grep "xyz occured" file.log | cut -d\ -f2`
do
grep $x file.log
done
The thing I like about this method is if you wanted to you could write the output to a file for each status code.
grep $x file.log >> /var/tmp/$x.out
This is all about retrieve the files in a narrowed search scope. In your case the search scope is determined by a file content.
I have found this problem more often while reducing the search scope through many searches (applying filters to the previous grep results).
Trying to find general answer:
Generate a list with the result of the first grep:
grep pattern | awk -F':' '{print $1}'
Second grep into the list of files like here
xargs grep -i pattern
apply this cascading filter the times you need just adding awk to get only the filenames and xargs to pass the filenames to grep -i
For example:
grep 'pattern1' | awk -F':' '{print $1}' | xargs grep -i 'pattern2'
Just use awk:
awk '{info[$2] = info[$2] $0 ORS} /xyz occured/{ids[$2]} END{ for (id in ids) printf "%s",info[id]}' file.log
or:
awk '/status code/{code[$2]=$NF} /xyz occured/{ids[$2]} END{ for (id in ids) print code[id]}' file.log
depending what you really want to output. Some expected output in your question would help.
Grep the result of a previous Grep:
Given this file contents:
ID 1000 xyz occured
ID 1001 misc content
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content
ID 1001 misc content
This command:
grep "xyz" file.log | awk '{ print $2 }' > f.log; grep `cat f.log` file.log;
returns this:
ID 1000 xyz occured
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content
It looks for "xyz" in file.log places the result in f.log. Then greps for that ID in file.log. If the outer grep returns multiple ID numbers, then the inner grep will only search the first ID number and error out on the others.

under mac terminal: List all of the users whom has at least one running process?

how to list all of the users whom has at least one running process.
The user name should not be duplicated.
The user name should be sorted.
$ ps xau | cut -f1 -d " "| sort | uniq | tail -n +2
You may want to weed out names starting with _ as well like so :
ps xau | cut -f1 -d " "| sort | uniq | grep -v ^_ | tail -n +2
users does what is requested. From the man page:
users lists the login names of the users currently on the system, in
sorted order, space separated, on a single line.
Try this:
w -h | cut -d' ' -f1 | sort | uniq
The w -h displays all users in system, without header and some output. The cut part removes all other information without username. uniq ignores duplicate lines.

Resources