![/etc/passwd에서 grep을 사용하여 나열된 모든 사용자 홈 디렉토리를 찾아야 합니다.](https://rvso.com/image/89172/%2Fetc%2Fpasswd%EC%97%90%EC%84%9C%20grep%EC%9D%84%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20%EB%82%98%EC%97%B4%EB%90%9C%20%EB%AA%A8%EB%93%A0%20%EC%82%AC%EC%9A%A9%EC%9E%90%20%ED%99%88%20%EB%94%94%EB%A0%89%ED%86%A0%EB%A6%AC%EB%A5%BC%20%EC%B0%BE%EC%95%84%EC%95%BC%20%ED%95%A9%EB%8B%88%EB%8B%A4..png)
개인이 /etc/passwd에서 grep 또는 awk를 사용하여 모든 사용자 목록을 찾아야 하는 이 사이트의 다른 질문과 유사한 질문이 있습니다. 그것은 나에게 효과적이었지만 홈 디렉토리를 찾고 나열하기 위해 번역을 시도했습니다. 나는 이미 한 줄로 할 수 없다는 것을 알고 있으므로 파이프라인을 사용할 것이라는 것을 알고 있습니다. 온라인으로 조사를 해봤지만 문제가 무엇인지 알 수 없습니다. grep을 사용하고 다음과 같은 작업을 수행하면:
grep -oE '^[/*/]$' /etc/passwd
...아마도 오류가 발생하거나 내가 원하는 것이 아닌 /bin/bash 파일도 표시될 것입니다. grep을 사용하여 나열된 사용자 이름과 홈 디렉토리만 있으면 됩니다! 또한 일부 홈 디렉토리에는 /(슬래시)가 두 개 이상 있기 때문에 *가 다른 슬래시를 문자로 표시할지 확실하지 않습니다.
답변1
답변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
이는 이에 대한 최선의 도구가 아닙니다. 당신이 그것을 사용하기를 고집하고 당신이 (줄의 일치하는 부분만 인쇄) 및 (Perl 호환 정규식 사용)을 grep
지원 한다면 다음을 수행할 수 있습니다:-o
-P
$ 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
) 인쇄되지 않습니다. 그런 다음 :
뒤에 :
and non- 가 오는 non- 문자열과 일치합니다 :
. 그만큼(?=foo)
A라고 불린다.긍정적인 예측문자를 일치시키는 방법입니다~ 후에일치 자체에 해당 문자를 포함하지 않는 패턴입니다.
이 명령은 현재 줄 번호( )가 2로 나눌 수 있는 경우 perl
줄 바꿈을 공백으로 바꿉니다 . 즉, 두 번째 줄마다입니다.:
$.
답변4
나는 "컷"을 사용하여 하나의 바이너리만 사용하고 파이프를 피하고 다른 답변과 동일한 결과에 도달하지만 더 우아한 방법으로 이 작업을 수행할 수 있다고 믿습니다. :) 다음과 같습니다.
$ 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