I would like to know whether is a way to print the longest name of the usernames in linux. Can it be done?
-
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 ♦Jun 17, 2018 at 9:47
-
2What 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.– Mark PlotnickJun 17, 2018 at 11:45
4 Answers
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.
-
Possible typo. I think you mean: "(the 1st
:
delimited string)" as the output ofgetent
is delimited by:
. Jun 17, 2018 at 10:15 -
@NasirRiley Yep, that's my finger slipping off the shift key. Thanks.– Kusalananda ♦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}}'
Jun 17, 2018 at 12:16 -
-
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.– doneal24Jun 17, 2018 at 18:45
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.
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.
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
-
This does not take into account the possibility of users authenticated though LDAP, Active Directory, or any other remote authentication source.– doneal24Jun 17, 2018 at 18:46