4

What commands can I use to display all users who have an identifier (UID) that is greater than 10?

3 Answers 3

10

You can parse the passwd database using awk. In the passwd format, each entry is a list of fields delimited by :, with the first field being the username and the third field being the UID. So, in awk, you could do:

getent passwd | awk -F: '$3 > 10 {print $1}'
3
  • You may simply awk -F ':' '$3 > 10' /etc/passwd . print is the default behavior, less typing
    – Panther
    May 11, 2015 at 23:58
  • 1
    @bodhi.zazen as a frequent user of LDAP systems, I see no reason not to use getent. And I suppose OP only wants the username.
    – muru
    May 11, 2015 at 23:59
  • through python, with open(file) as f: for line in f: m = line.split(':'); if int(m[2]) > 10: print(m[0]) . Note that this is not an one-liner. May 12, 2015 at 5:28
3

SOLUTION 1 :

You can use:

#!/bin/bash
while IFS= read -r line; do
    [[ "$(cut -d: -f3 <<<"$line")" -gt 10 ]] && echo "$line"
done </etc/passwd

Considering you have no username containing :.

If you just want the usernames:

#!/bin/bash
while IFS= read -r line; do
    [[ "$(cut -d: -f3 <<<"$line")" -gt 10 ]] && echo "$(cut -d: -f1 <<<"$line")"
done </etc/passwd

Here we are reading each line of the /etc/passwd file and comparing the third field delimited by : (UID) to check whether it is greater than 10. If it is true, we have printed the line (or username in second script).

This would be much simpler using an array (thanks to muru):

#!/bin/bash
while IFS=: read -a line; do
    [[ "${line[2]}" -gt 10 ]] && echo "${line[0]}"
done </etc/passwd

SOLUTION 2 :

Using grep with PCRE:

getent passwd | grep -P '^[^:]+:[^:]+:(?!(?:\d|10):)' | cut -d: -f1
  • ^[^:]+: will match the first field (username) including trailing :

  • [^:]+: will match the second field (password) including trailing :

  • (?!(?:\d|10):) part is tricky, it is a zero width negative lookahead patern of PCRE (grep -P), it means there is no single digit (\d) number or number 10 next, followed by a :.

  • cut -d: -f1 will just print the first field (username).

Alternately, you can avoid the cut, by using the negative lookahead (?!) inside of the positive lookahead (?=) pattern (thanks to Avinash Raj) :

getent passwd | grep -Po '^[^:]+(?=:[^:]+:(?!(?:\d|10):))'

SOLUTION 3 :

using python :

#!/usr/bin/env python2
with open('/etc/passwd') as f:
    print '\n'.join([line.split(':')[0] for line in f if int(line.split(':')[2]) > 10])

Here we are printing usernames if the third field is grater than 10. line.split(':') will split fields of each line on :, making it a list of fields.

4
  • Set IFS=:, and use read -a, then you can use ${line[0]} and ${line[2]} directly.
    – muru
    May 12, 2015 at 0:07
  • @muru thank you very much..i have not thought it that way..adding..
    – heemayl
    May 12, 2015 at 0:08
  • @heemayl i think you may try ^[^:]+(?=:[^:]+:(?!(?:\d|10):)), you don't need for cut command. May 12, 2015 at 5:24
  • @AvinashRaj Thank you very much..neat..added..
    – heemayl
    May 12, 2015 at 9:52
1

Using awk:

 awk -F: '{if ($3 > 10) { print $1 ":" $3 } }' /etc/passwd

this will list all users with their associated UID where UID > 10.

Thanks to @sadi note, to list only usernames

awk -F: '{if ($3 > 10) {print $1}}' /etc/passwd
3
  • 1
    This lists all usernames followed by a column and UID. However this lists usernames only: awk -F: '{if ($3 > 10) {print $1}}' /etc/passwd
    – Sadi
    May 12, 2015 at 7:43
  • @Sadi thanks but I insert the UID to show each User with its associated UID
    – Maythux
    May 12, 2015 at 7:45
  • I understand; I just wanted to add a note how to modify this in case only usernames are required - UpVoted ;-)
    – Sadi
    May 12, 2015 at 7:47

You must log in to answer this question.

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