2

I would like to know whether is a way to print the longest name of the usernames in linux. Can it be done?

2
  • The title and text conflict. Do you want the longest username, or the longest real name? The text says "longest name of the usernames", which seems to mean something other than the actual username.
    – Kusalananda
    Commented Jun 17, 2018 at 9:47
  • 2
    What if there are two usernames that are the same length? Print both or just one? If this is homework, please give us the complete text of the assignment. Commented Jun 17, 2018 at 11:45

4 Answers 4

4

To get the longest username (and its length):

$ getent passwd | awk -F':' '{ print length($1), $1 }' | sort -rn | head -n 1
11 _traceroute

That is, get the passwd file, compute the length of each username (the 1st :-delimited string), sort by length and pick the first.

If there are several usernames of the same length, the one that sorts last lexicographically is picked.

To get the longest real name (and see what username its the real name of, and the length):

$ getent passwd | awk -F':' '{ print length($5), $1, $5 }' | sort -rn | head -n 1
32 _rtadvd IPv6 Router Advertisement Daemon

This does the same thing as the first command, but it computes the length of the 5th :-delimited string in the passwd file. This field contains the real name of the user. The output is the length of the real name, the username, and the real name.

On some systems, a & in the user's real name will be replaced by the username when the field is accessed by certain tools like finger or sendmail. For example, a passwd entry may be

operator:*:2:5:System &:/operator:/sbin/nologin

To take this into account when calculating the length of the real name:

getent passwd | awk -F':' '{ gsub("&", $1, $5); print length($5), $1, $5 }' | sort -rn | head -n 1

Further letting awk select the longest name, getting rid of the sort and head:

getent passwd |
awk -F':' '
          { gsub("&", $1, $5) ; len = length($5)      }
len > max { line = $0         ; max = len;            }
END       { split(line, a, FS); print max, a[1], a[5] }'

With this code, the first found longest name will be picked if there are several names of the same length.

5
  • Possible typo. I think you mean: "(the 1st : delimited string)" as the output of getent is delimited by :. Commented Jun 17, 2018 at 10:15
  • @NasirRiley Yep, that's my finger slipping off the shift key. Thanks.
    – Kusalananda
    Commented Jun 17, 2018 at 10:17
  • With GNU awk > 4.0 you could do the sorting and selection natively e.g. gawk -F: '{a[$1]=length($1); next} END {PROCINFO["sorted_in"]="@val_num_desc"; for(x in a) {print x; break}}' Commented Jun 17, 2018 at 12:16
  • @steeldriver I added another way of doing it.
    – Kusalananda
    Commented Jun 17, 2018 at 12:23
  • getent passwd might not enumerate all the possible usernames. If, for instance, you're using sssd accessing an Active Directory domain, only the entries in /etc/passwd will be shown even though many other accounts have access to the system. I don't know of any any to enumerate these accounts to find the longest username. I would assume in my environment that the longest account name is the AD length limit of 20 characters but I cannot confirm that.
    – doneal24
    Commented Jun 17, 2018 at 18:45
1

This is pretty unoptimized, but since you don't usually have tens of thousands of users in a slow database, it might do:

getent passwd | cut -d: -f1 \
| grep $(getent passwd | cut -d: -f1 | tr '[:print:]' '.' | sort | tail -n1)

Let's unpick this thing a bit: getent passwd will list the user database. The lines in there are of the form

root:x:0:0:root:/root:/bin/bash

Username, x, UID, GID, GECOS (usually Human-readable user name now), home directory, shell. We use cut -d:1 -f1 to cut away everything but the first :-delimited field, i.e. the username.

In total, we're doing that twice: once to find the length of the longest username (line 2) and then to actually find usrenames of this length.

To find the length of the longest username, we just use tr to swap all characters for .s. Then, we can simply sort the list and know that the longest string of .s is last, so we obtain that with tail -n1. (Technically this requires that there's always at least one user, but there's root, so that's a fairly safe assumption.)

Now we have a string of dots that is as long as the longest user name. We're lucky it's dots, because . is the wildcard for "any character" for regular expressions, so we use grep to match all usernames against this string of spaces, and only the longest will match.

(FWIW, on my CentOS box, it was systemd-network.)

If you want the human-readable names, you basically just want cut -d: -f5 instead.

1

I have a file that contains first name, last name, and email address of users. Here is what I did to print the longest first name:

awk '{print length($1), $1}' filename | sort -nr | head -1| cut -d\  -f2

Feel free to tweak it per your preference. Note that you hit two spaces after -d\

To print the longest username, you can use

grep -v "^#" /etc/passwd | awk -F: '{print length($1), $1}' | sort -nr | head -1 | cut -d\  -f2

To print the real user name, use

grep -v "^#" /etc/passwd | awk -F: '{print length($5), $5}' | sort -nr | head -1 | cut -d\  -f2-

You put a dash after -f2 at the end to make sure that you get spaces in the user's real name.

0

Below are Top 10 longest usernames excluding the system users

sed -n '/sbin/!p' /etc/passwd|  awk -F ":" '{print length($1),$1}'| sort -k1 -nr| head

output

   9 praveen10
9 lost_foud
8 p2_final
7 praveen
6 p1_new
5 user5
5 user4
5 user3
5 user2
5 user1
1
  • This does not take into account the possibility of users authenticated though LDAP, Active Directory, or any other remote authentication source.
    – doneal24
    Commented Jun 17, 2018 at 18:46

You must log in to answer this question.

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