Intereting Posts
Конфигурация порта не работает как отключенная Linux встроен: изменить часовой пояс Скопируйте конкретный подкаталог и сохраните структуру дерева каталогов несоответствие между путями для двоичной и служебной страницы Сохранение строк в разные файлы на основе даты Можно ли отправить ярлык на два приложения (например, Audacity и VLC) и в одно и то же время? man: скрыть справочное сообщение Linux возобновляет использование нескольких разделов подкачки Когда Samba работал в manjoro linux, демону не удалось запустить: Samba обнаружила неправильно сконфигурированную «роль сервера» и вышла. Чтение номеров из файла управления и извлечение совпадающих номеров строк из файла данных Есть ли способ проверить команду find (сравнить с локацией)? Как загрузиться в initramfs? Полный вид того, где переменная PATH задана в bash Создание запроса подписи сертификата для SSL-сервера Как установить mod_mono на Linux Mint?

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

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

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

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

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 Является ли файл, который мы обрабатываем

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

 cut -d: -f6 /etc/passwd 

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

Как отмечали другие, grep – не лучший инструмент для этого. Если вы настаиваете на его использовании, и если ваш grep поддерживает -o (только распечатать согласованную часть строки) и -P (использовать Perl Compatible Regular Expressions), вы можете сделать это:

 $ 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 

объяснение

Регулярное выражение имеет две части: он ищет ^[^:]+ ИЛИ (это то, что означает | ) .*:\K[^:]+(?=:[^:]+) . Первый ищет один или несколько символов : от начала строки. Это соответствует имени пользователя. Вторая часть ищет как можно больше символов, пока не будет : ( .*: :), А затем отбросит их (это то, что делает \K ), поэтому они не печатаются. Затем он соответствует строке non : которой следуют : и не : Конструкция (?=foo) называется положительным взглядом и является способом сопоставления символов после шаблона без включения этих символов в совпадение.

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

Я считаю, что вы можете сделать это с помощью «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 

Надеюсь это поможет :)! С уважением!