Como otros han señalado, grepno es la mejor herramienta para esto. Si insiste en usarlo, y si grepadmite -o(solo imprima la parte coincidente de la línea) y -P(use Expresiones regulares compatibles con Perl), puede hacer esto:
$ grep -oP '^[^:]+|.*:\K[^:]+(?=:[^:]+)' /etc/password
terdon
/home/terdon
bob
/home/bob
Tenga en cuenta que esto imprimirá a todos los usuarios, incluidos los usuarios del sistema. Solo estoy mostrando 4 líneas como ejemplo.
Eso imprimirá el nombre de usuario y los directorios de inicio de todos los usuarios, pero en líneas separadas. Luego debe unir cada par de líneas para unirlas:
$ 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
Explicación
La expresión regular tiene dos partes, busca ^[^:]+OR (eso es lo que |significa) .*:\K[^:]+(?=:[^:]+). El primero busca uno o más no :caracteres desde el principio de la línea. Esto coincide con el nombre de usuario. La segunda parte busca tantos caracteres como sea posible hasta a :( .*:) y luego los descarta (eso es lo que \Khace) para que no se impriman. Luego coincide con una cadena de non- :que es seguida por :y non- :. La (?=foo)construcción se denomina anticipación positiva y es una forma de hacer coincidir los caracteres después de un patrón sin incluir esos caracteres en la coincidencia misma.
El perlcomando reemplazará las nuevas líneas con :y espacios si el número de línea actual ( $.) es divisible por 2. Entonces, cada segunda línea.
/etc/passwdpuede o no estar donde están todos los usuarios. Tenga en cuenta tambiéngetent passwd.