除第一个单词外,其他行完全相同,将第一个单词放入变量中

除第一个单词外,其他行完全相同,将第一个单词放入变量中

我有一个文件 (sudoers),其中的行除了第一个单词外可以完全相同(不同的用户可以执行同一组命令)。我可以使用以下命令提取这样的行:

# grep -v '^ *%' /etc/sudoers |egrep "$users_in_which_I_am_interested | sort|awk '{sub(/^[ \t]+/, "")};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 在此之前已准备好删除前导和尾随制表符和空格,并将单词之间的所有多个空格替换为单个空格)。除了用户之外,这些行是相同的。我希望能够提取具有相同命令语句、配置了相同权限但不同用户的行,并将用户名分配给变量并通过循环运行它。

# grep -v '^ *%' /etc/sudoers |egrep "$users_in_which_I_am_interested | sort|awk '{sub(/^[ \t]+/, "")};1'| uniq -cf 1
4 tom ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser

我的问题就在这里 - 如何找到文件中包含以下内容的所有行

"ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser"

并将这些行中的用户分配给变量?对字符串进行“grep”并不容易,它是一个未知字符串,可能包含许多必须转义的字符。可以使用 ksh、awk 和 sed(不能使用 perl/python 和其他 scr. 语言)。

答案1

awk '
  {user = $1; $1 = ""; users[$0] = users[$0] sep user; sep = " "}
  END {for (key in users) {print key ">" users[key]}}
'

根据您的样本输入,这将产生

 ALL = NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser>tom jim mark peter

答案2

我知道您不想要 perl 解决方案,但无论如何这里有一个。它的优点是它可以处理允许的命令的顺序不同。

因此
NOPASSWD:/usr/bin/pwdadm,/usr/bin/chsec,/usr/bin/chuser
被视为等于
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";
}

相关内容