awk ' END } '
Bei gegebenem Probeneingang wird dies erzeugt
ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser>tom jim mark peter
Ich habe eine Datei (Sudoers), in der die Zeilen mit Ausnahme des ersten Wortes in ihnen identisch sein können (verschiedene Benutzer können denselben Befehlssatz ausführen). Ich kann eine solche Zeile mit dem Befehl extrahieren:
# grep -v '^ *%' /etc/sudoers |egrep "$users_in_which_I_am_interested | sort|awk ';1' tom ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser jim ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser mark ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser peter ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser
(/ etc / sudoers ist davor vorbereitet, führende und nachgestellte Tabulatoren und Leerzeichen zu entfernen und alle Leerzeichen zwischen Wörtern durch ein Leerzeichen zu ersetzen). Diese Zeilen sind bis auf den Benutzer identisch. Ich möchte in der Lage sein, Zeilen zu extrahieren, die dieselben Befehlsanweisungen mit denselben Berechtigungen, aber unterschiedlichen Benutzern konfiguriert haben, und den Benutzernamen einer Variablen zuzuweisen und ihn durch eine Schleife auszuführen.
# grep -v '^ *%' /etc/sudoers |egrep "$users_in_which_I_am_interested | sort|awk ';1'| uniq -cf 1 4 tom ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser
Das Problem für mich kommt hier - wie finde ich alle Zeilen in der Datei, die enthalten
"ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser"
und den Benutzer in diesen Zeilen einer Variablen zuordnen? "grep" -Eingabe für die Zeichenfolge ist nicht leicht möglich, es handelt sich um eine unbekannte Zeichenfolge und enthält möglicherweise viele Zeichen, die mit Escapezeichen versehen werden müssen. ksh, awk und sed können verwendet werden (keine Perl / Python und andere Scr.-Sprachen).
awk ' END } '
Bei gegebenem Probeneingang wird dies erzeugt
ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser>tom jim mark peter
Ich weiß, du wolltest keine Perl-Lösung, aber hier ist sowieso eine. Es hat den Vorteil, dass es damit umgehen kann, wenn sich die erlaubten Befehle in einer anderen Reihenfolge befinden.
Also
NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser
wird gleich behandelt
NOPASSWD:/usr/bin/chuser,/usr/bin/pwdadm,/usr/bin/chsec
#!/bin/perl use strict; use warnings; my %hash; # reads all lines from STDIN while(<>) { chomp; # removes leading/trailing whitespace #splits the input string on whitespace my ($user, undef, undef, $cmds) = split; # pulls out list of allowed commands my($NP, $cmdlist) = split(/:/, $cmds); # Sorts the list of commands and puts it together again $cmds = "$NP:".join(',', sort split(/,/, $cmdlist)); # if the command exists in the hash with a user # add the nest user else just adds user $hash{$cmds} = $hash{$cmds}? "$hash{$cmds} $user" : $user; } # print all foreach my $key (keys %hash) { print "$key | ", $hash{$key} ,"\n"; }