Como otros han señalado, grep
no es la mejor herramienta para esto. Si insiste en usarlo, y si grep
admite -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 \K
hace) 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 perl
comando 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/passwd
puede o no estar donde están todos los usuarios. Tenga en cuenta tambiéngetent passwd
.