Zeilen, die bis auf ihr erstes Wort identisch sind, setzen das erste Wort in eine Variable

435
Sims

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).

0

2 Antworten auf die Frage

1
glenn jackman
awk '  END } ' 

Bei gegebenem Probeneingang wird dies erzeugt

 ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser>tom jim mark peter 
Es wundert mich immer wieder, wie viel man mit awk machen kann Nifle vor 13 Jahren 0
0
Nifle

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"; }