正如其他人指出的那样,grep
这不是最好的工具。如果您坚持使用它,并且grep
支持-o
(仅打印行中匹配的部分)和-P
(使用与Perl兼容的正则表达式),则可以执行以下操作:
$ grep -oP '^[^:]+|.*:\K[^:]+(?=:[^:]+)' /etc/password
terdon
/home/terdon
bob
/home/bob
请注意,这将打印所有用户,包括系统用户。我仅以4行为例。
这将在单独的行上打印所有用户的用户名和主目录。然后,您需要加入每对线以使它们在一起:
$ 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
说明
正则表达式有两个部分,它查找^[^:]+
OR(这|
意味着).*:\K[^:]+(?=:[^:]+)
。第一个:
从行首查找一个或多个非字符。这与用户名匹配。第二部分将查找尽可能多的字符,直到:
(.*:
),然后将其丢弃(这就是这样\K
做的原因),以便不打印它们。然后,它匹配字符串non- :
,后跟:
and non- :
。该(?=foo)
构造称为正向超前,是一种在模式之后匹配字符而不在匹配项本身中不包含这些字符的方式。
如果当前行号()被2整除,该perl
命令将用:
和替换换$.
行。
/etc/passwd
可能或可能不是所有用户所在的地方。也考虑一下getent passwd
。