![Preciso encontrar todos os diretórios iniciais dos usuários listados usando grep de /etc/passwd](https://rvso.com/image/89172/Preciso%20encontrar%20todos%20os%20diret%C3%B3rios%20iniciais%20dos%20usu%C3%A1rios%20listados%20usando%20grep%20de%20%2Fetc%2Fpasswd.png)
Tenho uma pergunta semelhante a outra neste site, onde o indivíduo precisava encontrar uma lista de todos os usuários usando grep ou awk em/etc/passwd. Isso funcionou para mim, mas tentei traduzi-lo para encontrar e listar os diretórios pessoais deles também. Eu já sei que você não pode fazer isso em uma linha, então sei que usaria um pipeline. Fiz minha pesquisa on-line, mas não consigo descobrir qual é o problema. Se eu usar grep e fizer algo como o seguinte:
grep -oE '^[/*/]$' /etc/passwd
... provavelmente me daria um erro ou também me mostraria os arquivos /bin/bash que não são o que eu quero. Eu só preciso dos nomes de usuários e seus diretórios pessoais listados usando grep! Também não tenho certeza se o * mostrará outras barras como caracteres, já que alguns diretórios iniciais têm mais do que apenas dois /'s (barras).
Responder1
Você pode usarcut
para dividir arquivos com colunas em um delimitador específico:
cut -d: -f6 /etc/passwd
Ou -f1,6
para colunas (campos) 1 e 6.
Responder2
Grep não é realmente a ferramenta para analisar dados dessa maneira; grep é mais para correspondência de padrões e você está tentando processar texto. Você gostaria de usar o awk.
awk -F":" '$7 == "/bin/false" {print "User: "$1 "Home Dir: "$6}' /etc/passwd
awk
- O comando-F":"
– Define o delimitador de dados para:
$7 == "/bin/false"
– Verifica se a 7ª coluna de dados está/bin/false
{print "User: "$1 "Home Dir: "$6}'
– Diz para imprimir a primeira coluna e a sexta coluna no formato especificado./etc/passwd
– O arquivo que estamos processando
Responder3
Como outros apontaram, grep
não é a melhor ferramenta para isso. Se você insistir em usá-lo, e se você grep
suportar -o
(imprimir apenas a parte correspondente da linha) e -P
(usar expressões regulares compatíveis com Perl), você pode fazer o seguinte:
$ grep -oP '^[^:]+|.*:\K[^:]+(?=:[^:]+)' /etc/password
terdon
/home/terdon
bob
/home/bob
Observe que isso imprimirá todos os usuários, incluindo usuários do sistema. Estou mostrando apenas 4 linhas como exemplo.
Isso imprimirá o nome de usuário e os diretórios pessoais de todos os usuários, mas em linhas separadas. Você então precisa juntar cada par de linhas para juntá-los:
$ 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
Explicação
A regex tem duas partes, ela procura ^[^:]+
OR (é isso que |
significa) .*:\K[^:]+(?=:[^:]+)
. O primeiro procura um ou mais não- :
caracteres desde o início da linha. Isso corresponde ao nome de usuário. A segunda parte procura o máximo de caracteres possível até um :
( .*:
) e depois os descarta (é isso que \K
faz) para que não sejam impressos. Em seguida, ele corresponde a uma sequência de non- :
que é seguida por :
e non- :
. A (?=foo)
construção é chamada deantecipação positivae é uma forma de combinar os personagensdepoisum padrão sem incluir esses caracteres na própria partida.
O perl
comando substituirá novas linhas por :
espaços se o número da linha atual ( $.
) for divisível por 2. Portanto, a cada segunda linha.
Responder4
Acredito que você possa fazer isso com "cut", usando apenas um binário, evitando pipes, chegando aos mesmos resultados das outras respostas, mas de uma forma mais elegante :), assim:
$ 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
....
Se você quiser ter uma saída melhor formatada + ordem alfabética, aqui está, mas a desvantagem é que você precisa usar mais binários:
$ 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