![Ich muss alle aufgelisteten Benutzer-Home-Verzeichnisse mit grep aus /etc/passwd finden](https://rvso.com/image/89172/Ich%20muss%20alle%20aufgelisteten%20Benutzer-Home-Verzeichnisse%20mit%20grep%20aus%20%2Fetc%2Fpasswd%20finden.png)
Ich habe eine ähnliche Frage wie eine andere auf dieser Site, bei der die Person eine Liste aller Benutzer mit grep oder awk aus /etc/passwd finden musste. Das hat bei mir funktioniert, aber ich habe versucht, es zu übersetzen, um auch die Home-Verzeichnisse der Benutzer zu finden und aufzulisten. Ich weiß bereits, dass man das nicht in einer Zeile machen kann, also weiß ich, dass ich eine Pipeline verwenden würde. Ich habe online recherchiert, aber ich kann das Problem nicht herausfinden. Wenn ich grep verwende und etwas wie das Folgende mache:
grep -oE '^[/*/]$' /etc/passwd
...es würde mir wahrscheinlich einen Fehler geben oder es würde mir auch die /bin/bash-Dateien anzeigen, was ich nicht will. Ich brauche nur die Benutzernamen und ihre Home-Verzeichnisse, die mit grep aufgelistet werden! Ich bin mir auch nicht sicher, ob das * andere Schrägstriche als Zeichen anzeigt, da einige Home-Verzeichnisse mehr als nur zwei / (Schrägstriche) haben.
Antwort1
Sie könnencut
So teilen Sie Dateien mit Spalten auf einem bestimmten Trennzeichen auf:
cut -d: -f6 /etc/passwd
Oder -f1,6
für die Spalten (Felder) 1 und 6.
Antwort2
Grep ist nicht wirklich das richtige Tool, um Daten auf diese Weise zu analysieren. Grep ist eher für Mustervergleiche gedacht und Sie versuchen, Textverarbeitung durchzuführen. Sie sollten awk verwenden.
awk -F":" '$7 == "/bin/false" {print "User: "$1 "Home Dir: "$6}' /etc/passwd
awk
- Der Befehl-F":"
– Setzt das Datentrennzeichen auf:
$7 == "/bin/false"
– Prüft, ob die 7. Datenspalte/bin/false
{print "User: "$1 "Home Dir: "$6}'
– Gibt an, dass die erste und die sechste Spalte im angegebenen Format gedruckt werden sollen./etc/passwd
– Ist die Datei, die wir verarbeiten
Antwort3
Wie andere bereits angemerkt haben, grep
ist dies nicht das beste Tool dafür. Wenn Sie darauf bestehen, es zu verwenden, und Ihr Programm grep
die Funktionen -o
(nur den übereinstimmenden Teil der Zeile drucken) und -P
(Perl-kompatible reguläre Ausdrücke verwenden) unterstützt, können Sie Folgendes tun:
$ grep -oP '^[^:]+|.*:\K[^:]+(?=:[^:]+)' /etc/password
terdon
/home/terdon
bob
/home/bob
Beachten Sie, dass hierdurch alle Benutzer gedruckt werden, einschließlich Systembenutzer. Ich zeige nur 4 Zeilen als Beispiel.
Dadurch werden die Benutzernamen und Home-Verzeichnisse aller Benutzer gedruckt, allerdings in separaten Zeilen. Anschließend müssen Sie jedes Zeilenpaar zusammenfügen, um sie zusammenzufügen:
$ 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
Erläuterung
Der reguläre Ausdruck besteht aus zwei Teilen, er sucht nach ^[^:]+
OR (das |
bedeutet das) .*:\K[^:]+(?=:[^:]+)
. Der erste Teil sucht nach einem oder mehreren Nicht- :
Zeichen vom Anfang der Zeile. Dies entspricht dem Benutzernamen. Der zweite Teil sucht nach so vielen Zeichen wie möglich, bis ein :
( .*:
) erscheint, und verwirft sie dann (das macht das \K
), damit sie nicht gedruckt werden. Er gleicht dann eine Zeichenfolge aus Nicht- ab, :
auf die :
und Nicht- folgen :
. Die (?=foo)
Konstruktion heißt apositiver Ausblickund ist eine Möglichkeit, die Zeichen zuzuordnennachein Muster, ohne diese Zeichen in die Übereinstimmung selbst einzubeziehen.
Der perl
Befehl ersetzt Zeilenumbrüche durch :
Leerzeichen, wenn die aktuelle Zeilennummer ( $.
) durch 2 teilbar ist. Also jede zweite Zeile.
Antwort4
Ich glaube, dass Sie dies mit „cut“ erreichen können, indem Sie nur eine Binärdatei verwenden, Pipes vermeiden und dieselben Ergebnisse wie die anderen Antworten erzielen, jedoch auf elegantere Weise :), und zwar so:
$ 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
....
Wenn Sie eine besser formatierte und alphabetisch sortierte Ausgabe wünschen, können Sie dies tun. Der Nachteil dabei ist jedoch, dass Sie mehr Binärdateien verwenden müssen:
$ 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