Мне нужно найти все домашние каталоги пользователей, перечисленные с помощью grep из /etc/passwd

Мне нужно найти все домашние каталоги пользователей, перечисленные с помощью grep из /etc/passwd

У меня есть вопрос, похожий на другой на этом сайте, где человек должен был найти список всех пользователей, использующих grep или awk из /etc/passwd. Это сработало для меня, но я пытался перевести это, чтобы найти и перечислить их домашние каталоги также. Я уже знаю, что вы не можете сделать это в одну строку, поэтому я знаю, что я бы использовал конвейер. Я провел свое исследование в Интернете, но я не могу понять, в чем проблема. Если я использую grep и делаю что-то вроде следующего:

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

...вероятно, это выдаст мне ошибку или также покажет мне файлы /bin/bash, что мне не нужно. Мне просто нужны имена пользователей и их домашние каталоги, перечисленные с помощью grep! Я также не уверен, покажет ли * другие прямые слеши как символы, так как некоторые домашние каталоги имеют больше, чем просто два / (прямых слеша).

решение1

Вы можете использоватьcutдля разделения файлов со столбцами по определенному разделителю:

cut -d: -f6 /etc/passwd

Или -f1,6для столбцов (полей) 1 и 6.

решение2

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– Файл, который мы обрабатываем?

решение3

Как уже указывали другие, 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), чтобы они не выводились. Затем оно сопоставляет строку не- , :за которой следует :и не- :. (?=foo)Конструкция называетсяпозитивный взгляд впереди это способ сопоставления персонажейпослешаблон без включения этих символов в само совпадение.

Команда perlзаменит символы новой строки на :пробелы, если номер текущей строки ( $.) делится на 2. То есть, каждая вторая строка.

решение4

Я считаю, что это можно сделать с помощью «cut», используя только один двоичный файл, избегая конвейеров и достигая тех же результатов, что и другие ответы, но более элегантным способом :), например так:

$ 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

Связанный контент