8

I have a question similar to another one on this site where the individual had to find a list of all users using grep or awk from /etc/passwd. That worked for me but I've tried translating it to find and list the home directories of them also. I already know you can't do it in one line so I know I would use a pipeline. I've done my research online but I can't figure it out the problem is. If I use grep and do something like the following:

   grep -oE '^[/*/]$' /etc/passwd 

...i t would probably give me an error or it will also show me the /bin/bash files which is not what I want. I just need the user names and their home directories listed using grep! I'm also not sure if the * will show other forward-slashes as characters, as some home directories have more than just two /'s (forward-slashes).

  • 3
    Also, /etc/passwd may or may not be where all the users are. Consider also getent passwd. – thrig Jun 22 '16 at 19:44
10

Grep is really not the tool for parsing out data this way, grep is more for pattern matching and you're trying to do text-processing. You would want to use awk.

awk -F":" '$7 == "/bin/false" {print "User: "$1 "Home Dir: "$6}' /etc/passwd

awk The command

-F":" Sets the data delimiter to :

$7 == "/bin/false" Checks if the 7th data column is /bin/false

{print "User: "$1 "Home Dir: "$6}' Says to print the first column and sixth column in the specified format.

/etc/passwd Is the file we're processing

  • I'm not too fond of awk could you explain what the -F: and '{print $1" "$6}' do exactly? – NarinderRSharma Jun 22 '16 at 19:41
  • I updated my answer to answer your question – Zachary Brady Jun 22 '16 at 19:44
  • yeah see for me when i do that it still shows me the password encryptions, UID GIDS what type of shell we are using. I need it to just print the users and they're home directories, nothing else. using grep or awk of course. – NarinderRSharma Jun 22 '16 at 19:51
  • when i use the following: grep -oE '^[^:]+' /etc/passwd that gives me just the users i need to pipline something like that or something similar to have the home directories there with them – NarinderRSharma Jun 22 '16 at 19:53
  • 1
    Can we see a sample (obfuscated) line from your etc passwd? It doesn't sound like it's : delimited or if it is, it's not laid out normally. – Zachary Brady Jun 22 '16 at 19:53
18

You can use cut to split files with columns on a specific delimiter:

cut -d: -f6 /etc/passwd

Or -f1,6 for columns (fields) 1 and 6.

  • 4
    Simple tools that do one job and do it well. Plus one! – fd0 Jun 22 '16 at 20:08
1

As others have pointed out, grep isn't the best tool for this. If you insist on using it, and if your grep supports the -o (only print the matched portion of the line) and -P (use Perl Compatible Regular Expressions), you can do this:

$ grep -oP '^[^:]+|.*:\K[^:]+(?=:[^:]+)' /etc/password
terdon
/home/terdon
bob
/home/bob

Note that this will print all users, including system users. I am only showing 4 lines as an example.

That will print the user name and home directories of all users but on separate lines. You then need to join each pair of lines to get them together:

$ grep -oP '^[^:]+|.*:\K[^:]+(?=:[^:]+)' /etc/passwd | perl -pe 's/\n/ : / if $.%2'
root : /root
bin : /bin
daemon : /
mail : /var/spool/mail
ftp : /srv/ftp
http : /srv/http
uuidd : /
dbus : /
nobody : /
systemd-journal-gateway : /
systemd-timesync : /
systemd-network : /
systemd-bus-proxy : /
systemd-resolve : /
systemd-journal-upload : /
systemd-coredump : /
systemd-journal-remote : /
terdon : /home/terdon
avahi : /
polkitd : /
colord : /var/lib/colord
rtkit : /proc
gdm : /var/lib/gdm
git : /
bob : /home/bob

Explanation

The regex has two parts, it looks for ^[^:]+ OR (that's what the | means) .*:\K[^:]+(?=:[^:]+). The first looks for one or more non-: characters from the beginning of the line. This matches the user name. The second part looks for as many characters as possible until a : (.*:) and then discards them (that's what the \K does) so they're not printed. It then matches a string of non-: which is followed by : and non-:. The (?=foo) construct is called a positive lookahead and is a way of matching the characters after a pattern without including those characters in the match itself.

The perl command will replace newlines with : and spaces if the current line number ($.) is divisible by 2. So, every second line.

  • perl can do the whole job with 'awk-mode' perl -naf: -e 'print $F[0]." : ".$F[5].$/' so sed 'N;s/\n/ : /' might be a better partner for grep -oP. – dave_thompson_085 Jun 23 '16 at 16:53
0

I believe that you can do this with "cut", using just one binary, avoiding pipes, reaching the same results as the other answers, but in a more elegant way :), like this:

$ cut -d : -f 1,6 /etc/passwd

root:/root
daemon:/usr/sbin
bin:/bin
sys:/dev
sync:/bin
games:/usr/games
man:/var/cache/man
lp:/var/spool/lpd
mail:/var/mail
news:/var/spool/news
....

If you wanna have an output better formatted + alphabetical order, here is, but the trade off is that, you have to use more binaries:

$ cut -d : -f 1,6 /etc/passwd | sort | column

avahi-autoipd:/var/lib/avahi-autoipd        man:/var/cache/man
avahi:/var/run/avahi-daemon                 messagebus:/var/run/dbus
backup:/var/backups                         news:/var/spool/news
bin:/bin                                    nobody:/nonexistent
clickpkg:/nonexistent                       ntp:/home/ntp
colord:/var/lib/colord                      proxy:/bin
daemon:/usr/sbin                            pulse:/var/run/pulse
dnsmasq:/var/lib/misc                       root:/root
games:/usr/games                            rtkit:/proc
gnats:/var/lib/gnats                        saned:/home/saned
hplip:/var/run/hplip                        speech-dispatcher:/var/run/speech-dispatcher
irc:/var/run/ircd                           sync:/bin
ivanleon:/home/ivanleon                     sys:/dev
kernoops:/                                  syslog:/home/syslog
libuuid:/var/lib/libuuid                    usbmux:/home/usbmux
lightdm:/var/lib/lightdm                    usermetrics:/var/lib/usermetrics
list:/var/list                              uucp:/var/spool/uucp
lp:/var/spool/lpd                           whoopsie:/nonexistent
lxc-dnsmasq:/var/lib/lxc                    www-data:/var/www
mail:/var/mail

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.