Рядки, однакові за винятком їхнього першого слова, ставлять перше слово в змінну


0

У мене є файл (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" -ing для рядка неможливий, це невідомий рядок і може містити безліч символів, які потрібно видалити. 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

Це завжди дивує мені скільки ви можете зробити з awk
Nifle

0

Я знаю, що ви не хочете вирішити проблему 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";
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.