I am realitively new to bash scripting, but have created this from my intense googling

I am attempting to create a bash script to run on Ubuntu that will check the user list and find any users that aren’t in a specified list. I have written this so far:

Cat /etc/passwd | grep -o -P ‘.{0,40}:1[0-9][0-9][0-9].{0,0}.’ | cut -d: -f1

views passwd file, then finds only the lines with a user ID of 1000 or above, and everything before the userID of each line is piped into cut which removes all except the username of each user.

I then want to have the script check a file for usernames I specify (probably copied from a list) and compare each to the output of the above. Removing all usernames specified.

So for instance:

I have users John, Ben and Tom on my computer If I put John and Ben in the file the script is accessing, it should output Tom since he is not specified

How would I go about doing this?

  • 1
    Have you heard of awk. I'm not very good at it but it's a well powerful programing language. ` awk -F: '{print $1}' /etc/passwd` lists all user id
    – rhubarbdog
    Dec 4, 2018 at 3:55
  • I'll experiment more with it, but when I run that, it also includes system users such as root, I'm only looking for user accounts that you can login as, such as a personal user account Dec 4, 2018 at 4:00
  • Yes but this is where awk becomes powerful because you can precede the print program with a pattern based on $2 the user number. I think you can put if statements in your program
    – rhubarbdog
    Dec 4, 2018 at 4:06

2 Answers 2


This code should work for you.

for username in $( awk -F':' '$3 >= 1000 {print $1}' /etc/passwd )
        if ! grep -q "$username" list.txt; then
                echo "$username"

Keep the usernames to check in list.txt as one user per line

  • 1
    This works almost perfectly, when i run it, i get the "nobody" user in the output aswell, is there any easy way to get around this? Dec 4, 2018 at 4:14
  • Simply change the awk condition to $3 >= 1000 && $1 != "nobody"
    – Kishor V
    Dec 4, 2018 at 10:36
  • ok, this entire thing is exactly what i was looking for thankyou! Dec 5, 2018 at 0:17

grep allows specifying patterns from file. Thus you can use grep -f option for that purpose and -v for inverse pattern matching, i.e. print lines not matching the pattern. Thus,

 printf "^%s\n" 'John' 'Ben' > /tmp/list.txt
 grep -v -f /tmp/list.txt  /etc/passwd | cut -d ':' -f 1
 rm l/tmp/ist.txt

We could also take into account UID greater than 999, since by default that refers to human users unless changed by your sysadmin.

awk -F ':' '$1 !~ /John|Ben|nobody/  && $3 > 999' /etc/passwd

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .