Как уже отмечали другие, 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[^:]+(?=:[^:]+)
. Первый ищет один или несколько не :
символов из начала строки. Это соответствует имени пользователя. Вторая часть ищет как можно больше символов до a :
( .*:
), а затем отбрасывает их (вот что \K
делает), чтобы они не печатались. Затем он соответствует строке non-, за :
которой следует :
и non- :
. (?=foo)
Конструкция называется положительным опережением и способ сопоставления символов после шаблона , не включая эти символы в самой игре.
Команда perl
заменит символы новой строки на :
и пробелы, если номер текущей строки $.
делится на 2. Итак, каждая вторая строка.
/etc/passwd
может или не может быть, где все пользователи. Учтите такжеgetent passwd
.