0

I want my grep to print a user list from /etc/passwd, and I've studied /etc/login.defs' minmax values for the ones I want my grep to fetch:

# Min/max values for automatic uid selection in useradd
#
UID_MIN          1000
UID_MAX         60000
# System accounts
#SYS_UID_MIN          100
#SYS_UID_MAX          999

Actual user IDs start at 1000 and finish at 60000, and system user IDs start at 100 and finish at 999.

So I made my script look like this (warning spanish text):

2)
echo 
echo "LISTA DE USUARIOS"
cat /etc/passwd | grep -E "*:[*-6][0-9][0-9][0-9][0-9]:*" | cut -d":" -f1
echo
echo "LISTA DE USUARIOS DEL SISTEMA"
cat /etc/passwd | grep -E "*:[1-9][0-9][0-9]:*" | cut -d":" -f1 
;;

It's obviously plain not working and grep is very hard for me so I'm not sure how to make it work. I tried (and always try) reading others' solutions but I think I'll need this one explained to me if I ever want to learn.

If possible I'm trying to avoid perl territory. I can't handle that much yet though I understand what it's famed for.

Anything else you need to know to help me, let me know.

Thanks! (also, first post ever here)

2
  • 2
    much easier to use a language that can do arithmetic comparisons e.g. awk -F: '$3>=1000' /etc/passwd Aug 24, 2015 at 19:59
  • @steeldriver I see, never really learned about that one, will investigate.
    – user442985
    Aug 24, 2015 at 20:00

4 Answers 4

1

This awk command does what you want. First, you set the record separator to : with FS=":", check if the third element is 1000-60000, and if so, print element 1 (username):

awk 'FS=":" {if ($3 > 999 && $3 < 60001) print $1}' < /etc/passwd
1
  • ...and fwiw, here's a Perl one-liner that does the same thing: perl -Mstrict -nE 'my @a=split /:/; if ($a[2] > 999 && $a[2] < 60001){ say $a[0]; }' /etc/passwd
    – stevieb
    Aug 24, 2015 at 21:14
1

Another awk version, with arrays. A bit more lengthy but working

awk -F':' ' $3 >= 1000 && $1 != "nobody" {i++;humanuser[i]=$1 } $3 < 999 { k++;sysuser[k]=$1} END {printf"****HUMAN USERS\n";for (j=1;j<=i;j++) printf humanuser[j]" "; printf "\n*****SYSTEM USERS\n"; for(m=1;m<=k;m++) printf sysuser[m]" "}' /etc/passwd

Sample output:

****HUMAN USERS
xieerqi testuser 
*****SYSTEM USERS
root daemon bin sys sync games man lp mail news uucp proxy www-data backup list irc gnats libuuid syslog messagebus usbmux dnsmasq avahi-autoipd kernoops rtkit saned whoopsie speech-dispatcher avahi lightdm colord hplip pulse gdm 
1
  • You could use UID_MIN=$(awk '/^#*UID_MIN/ {print $2}' /etc/login.defs); SYS_UID_MAX=$(awk '/^#*SYS_UID_MAX/ {print $2}' /etc/login.defs); awk -F':' ' $3 >= '"$UID_MIN"' && $1 != "nobody" {i++;humanuser[i]=$1 } $3 < '"$SYS_UID_MAX"' { k++;sysuser[k]=$1} END {printf"****HUMAN USERS\n";for (j=1;j<=i;j++) printf humanuser[j]" "; printf "\n*****SYSTEM USERS\n"; for(m=1;m<=k;m++) printf sysuser[m]" "}' /etc/passwd
    – A.B.
    Aug 25, 2015 at 6:03
0

You can use grep with Perl Compatible RegEx (PCRE) :

  • To get the usernames with UID >= 1000 :

    grep -Po '^[^:]+(?=:[^:]+:\d{4,})' /etc/passwd
    
  • To get the usernames with 100 <= UID <= 999 :

    grep -Po '^[^:]+(?=:[^:]+:\d{3})' /etc/passwd
    

Here -P indicates PCRE, -o indicates we are going to take only the matched portion.

  • ^[^:]+ gets us the username, everything upto first :

  • (?=) is zero width positive lookahead pattern, we are using this to ensure that we match our desired portion after the username

  • :[^:]+: matches :x: and then \d{4,} matches four or more digits (>=1000)

  • On the other hand :[^:]+: matched :x: then \d{3} matches exactly three digits (100 to 999).

0

DISCLAMER: The following java answer is for educational purposes and the fun of coding only. If you downvote, explain in the comments why.

Code

The code bellow reads each line from /etc/passwd , splits that line into strings with : as separator, and sorts users depending on their UID into appropriate ArrayLists.

package com.askubuntu.users.serg;

import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Scanner;

/**
 * 
 * A program to sort human and system users from /etc/password
 * 
 * @author Serg Kolo
 *
 */
public class UserList {
    private static final String SEPARATOR = "=============";
    private static final int SYS_UID_MAX = 999;
    private static final int UID_MAX = 1000;
    private static final String FILENAME_PASSWD = "/etc/passwd";
    private static final String COLON = ":";
    private static final String NOBODY = "nobody";

    /**
     * 
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) {
        File f = new File(FILENAME_PASSWD);
        try (Scanner readFile = new Scanner(f)) {
            ArrayList<String> humanUsers = new ArrayList<>();
            ArrayList<String> systemUser = new ArrayList<>();

            while (readFile.hasNext()) {
                String[] field = readFile.nextLine().split(COLON);
                int uid = Integer.parseInt(field[2]);

                if (uid >= UID_MAX && (!NOBODY.equals(field[0]))) {
                    humanUsers.add(field[0]);
                } else if (uid <= SYS_UID_MAX) {
                    systemUser.add(field[0]);
                }
            }
            printUsers(humanUsers, "Human Users:");
            printUsers(systemUser, "System Users:");
        } catch (FileNotFoundException e) {
            System.err.println(e.getLocalizedMessage());
        }
    }

    /**
     * 
     * print users
     * 
     * @param users
     * @param header
     */
    private static void printUsers(ArrayList<String> users, String header) {
        System.out.println(header);
        System.out.println(SEPARATOR);
        System.out.println(users);
        System.out.println();
    }
}

Procedure

  1. Save the code above as userlist.java
  2. Compile and run with your preferred Java IDE. If you prefer command line, do

    javac UserList.java && java UserList
    
  3. Output will appear in the console of your IDE

Sample output

Human Users:
=============
[xieerqi, testuser]
System Users:
=============
[root, daemon, bin, sys, sync, games, man, lp, mail, news, uucp, proxy, www-data, backup, list, irc, gnats, libuuid, syslog, messagebus, usbmux, dnsmasq, avahi-autoipd, kernoops, rtkit, saned, whoopsie, speech-dispatcher, avahi, lightdm, colord, hplip, pulse, gdm, sshd]

You must log in to answer this question.