Я хочу сравнить каждого пользователя в passwd файле с его записью в теневом файле и распечатать целую строку passwd файла, если запись в теневом файле соответствует 999999. Каков самый легкий путь в Perl, чтобы сделать это? Или я предполагаю, что мог awk значения из одного файла и соответствия в другом файле? Каков лучший способ сделать это?
awk -F":" 'FNR==NR&&$5=="99999"{user[$1];next}($1 in user)' /etc/shadow /etc/passwd
изменить FNR == NR && $ 5 == "99999"
на FNR == NR && $ 5 == "99999" && $ 2! = "!!"
, если вы хотите исключить строки с "!!"
sudo perl -F: -lane '(1..eof)?($_{$F[0]}=$_):/999999/&&($_=$_{$F[0]})&&print' /etc/passwd /etc/shadow
#! /usr/bin/perl
use warnings;
use strict;
sub read_passwd {
open my $fh, "<", "/etc/passwd" or die "$0: open: $!";
my %passwd;
while (<$fh>) {
next unless /^([^:]+)/;
$passwd{$1} = $_;
}
\%passwd;
}
my $passwd = read_passwd;
open my $fh, "<", "/etc/shadow" or die "$0: open: $!";
while (<$fh>) {
my($user,$maxage) = (split /:/)[0,4];
next unless $maxage eq 99999;
if ($passwd->{$user}) {
print $passwd->{$user};
}
else {
warn "$0: no passwd entry for '$user'";
}
}
Вы можете использовать AnyData :: Format :: Password :
#!/usr/bin/perl
use strict; use warnings;
use AnyData;
my $passwd = adTie(Passwd => 'passwd' );
my $shadow = adTie(Passwd => 'shadow' );
for my $user (keys %$shadow) {
if ( $user->{fullname} and $user->{fullname} eq '999999' ) {
print $passwd->{$user->{username}}{fullname}, "\n";
}
}
Вывод:
... Privilege-separated SSH RPC Service User Anonymous NFS User HAL daemon
Или:
for my $user (keys %$shadow) {
if ( $user->{fullname} and $user->{fullname} eq '999999' ) {
my @values = map { defined $_ ? $_ : '' }
@{ $passwd->{$user->{username}} }{@fields};
print join(':', @values), "\n";
}
}