我需要从/ etc / passwd查找使用grep列出的所有用户主目录


8

我有一个与此网站上的另一个问题类似的问题,该用户必须从/ etc / passwd中使用grep或awk查找所有用户的列表。这对我有用,但我尝试将其翻译以查找并列出它们的主目录。我已经知道您无法在一行中做到这一点,所以我知道我会使用管道。我已经完成了在线研究,但无法弄清楚问题出在哪里。如果我使用grep并执行以下操作:

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

...这可能会给我一个错误,或者还会显示/ bin / bash文件,这不是我想要的。我只需要使用grep列出的用户名和主目录!我也不确定*是否会将其他正斜杠显示为字符,因为某些主目录中的多个正斜杠不止两个。


3
同样,/etc/passwd可能或可能不是所有用户所在的地方。也考虑一下getent passwd
thrig

Answers:


10

Grep确实不是用这种方式解析数据的工具,而grep则更多地用于模式匹配,而您正在尝试进行文本处理。您可能要使用awk。

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

awk 命令

-F":" 将数据定界符设置为:

$7 == "/bin/false" 检查第7个数据列是否为/ bin / false

{print "User: "$1 "Home Dir: "$6}' 表示以指定格式打印第一列和第六列。

/etc/passwd 是我们正在处理的文件


我不太喜欢awk,您能解释一下-F:和'{print $ 1“” $ 6}'的功能吗?
NarinderRSharma

我更新了答案以回答您的问题
Zachary Brady 2016年

是的,我看到的时候仍然显示密码加密,UID GIDS,我们正在使用哪种类型的外壳。我只需要打印用户,他们就是主目录,别无其他。当然使用grep或awk。
NarinderRSharma

当我使用以下命令时:grep -oE '^[^:]+' /etc/passwd这给了我这些用户,我只需要提供类似的内容或类似的内容,即可将主目录保存在其中
NarinderRSharma

1
我们可以从您的etc passwd中看到示例行(模糊)吗?听起来好像不是:分隔,或者如果不是,则表示布局不正常。
Zachary Brady


1

正如其他人指出的那样,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命令将用:和替换换$.行。


perl可以使用“ awk-mode”完成整个工作,perl -naf: -e 'print $F[0]." : ".$F[5].$/'因此sed 'N;s/\n/ : /'可能是更好的合作伙伴grep -oP
dave_thompson_085

0

我相信您可以使用“剪切”来做到这一点,只使用一个二进制文件,避免使用管道,并获得与其他答案相同的结果,但是以一种更为优雅的方式:),如下所示:

$ 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
....

如果您想输出格式更好的+字母顺序的命令,可以这样做,但是要权衡的是,您必须使用更多的二进制文件:

$ 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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.