Eu preciso encontrar todos os diretórios home dos usuários listados usando grep de / etc / passwd

8

Eu tenho uma pergunta semelhante a outra neste site onde o indivíduo tinha que encontrar uma lista de todos os usuários usando grep ou awk de / etc / passwd. Isso funcionou para mim, mas eu 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 eu sei que usaria um pipeline. Eu fiz minha pesquisa on-line, mas não consigo entender o problema. Se eu usar o grep e fizer algo parecido com o seguinte:

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

... provavelmente me daria um erro ou também mostrará 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 home listados usando o grep! Eu também não tenho certeza se o * irá mostrar outras barras como caracteres, já que alguns diretórios home têm mais do que apenas dois / 's (barras).

    
por NarinderRSharma 22.06.2016 / 21:35

4 respostas

10

O grep não é realmente a ferramenta para analisar dados dessa maneira, o grep é mais para correspondência de padrões e você está tentando fazer processamento de 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 sétima coluna de dados é / 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

    
por 22.06.2016 / 21:40
18

Você pode usar cut para dividir arquivos com colunas em um delimitador específico:

cut -d: -f6 /etc/passwd

Ou -f1,6 para colunas (campos) 1 e 6.

    
por 22.06.2016 / 21:42
1

Como outros apontaram, grep não é a melhor ferramenta para isso. Se você insistir em usá-lo, e se o grep suportar o -o (apenas imprima a parte correspondente da linha) e -P (use expressões regulares compatíveis com Perl), você pode fazer isso:

$ grep -oP '^[^:]+|.*:\K[^:]+(?=:[^:]+)' /etc/password
terdon
/home/terdon
bob
/home/bob

Observe que isso imprimirá todos os usuários, incluindo os usuários do sistema. Estou mostrando apenas 4 linhas como exemplo.

Isso imprimirá o nome de usuário e os diretórios iniciais de todos os usuários, mas em linhas separadas. Você precisa então juntar cada par de linhas para juntá-las:

$ 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 o | significa) .*:\K[^:]+(?=:[^:]+) . O primeiro procura por um ou mais caracteres não- : desde o início da linha. Isso corresponde ao nome do usuário. A segunda parte procura pelo maior número possível de caracteres até um : ( .*: ) e, em seguida, descarta-os (é o que faz o \K ) para que não sejam impressos. Em seguida, ele corresponde a uma sequência de caracteres não : , seguida por : e não : . A construção (?=foo) é chamada de lookahead positivo e é uma maneira de corresponder os caracteres após em um padrão sem incluir esses caracteres no próprio jogo.

O comando perl substituirá as novas linhas com : e espaços se o número da linha atual ( $. ) for divisível por 2. Assim, a cada segunda linha.

    
por 23.06.2016 / 11:23
0

Acredito que você pode fazer isso com "cut", usando apenas um binário, evitando canos, atingindo os mesmos resultados que as 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ê quer ter uma saída melhor formatada + ordem alfabética, aqui está, mas a diferença é que, você tem que 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

Espero que isso ajude :)! Atenciosamente!

    
por 26.06.2016 / 15:35