对Perl来说很新,这让我很头疼。 我有一个文本文件,其中包含地址,电子邮件,日期等用户特定信息。我想将此文件与/ etc / passwd文件进行比较,如果passwd文件中存在用户名,则将数组中的etc / passwd数据合并,然后进一步操作。用户命名为字母数字,如“abc123”
这是我到目前为止所做的:
open PASSWD, "</etc/passwd" or die "$!"; # /etc/passwd file is opened to be searched for a matching username
open INFO, "<gtc_members.txt" or die "$!"; #information.txt is opened to search for matching user name
while (<PASSWD>) {
chomp;
my $userName = (split ":", $_)[0];
$homeDirectory = (split ":", $_)[5];
$fullName = (split ":", $_)[4];
$shell = (split ":", $_)[6];
push @userNames, ($fullName, $homeDirectory,$shell); # if $userName eq $searchName;
}
while (<INFO>) {
chomp;
my $userName1 = (split ",", $_)[2];
$userAddress = (split ",", $_)[3];
$userEmail = (split ",", $_)[4];
$userManager = (split ",", $_)[6];
push @userNames_1, ($userAddress,$userEmail,$userManager);# if $userName1 eq $searchName;
}
这就是我被困的地方。尽管尝试了不同的代码,但我无法将两个数组@userNames和@ userNames1合并到一个公共用户名上。它现在变得如此荒谬,以至于这一切都没有意义。我尝试过使用哈希,但很难匹配普通用户名,如本例所示。
答案 0 :(得分:1)
首先,永远不要直接解析/etc/passwd
。请改用getpw*
函数。第二,目前还不清楚你要对你将要获得的数据做什么,但你可以从中得到一个想法:
perl -F, -plae'if(my($fullName, $Dir, $Shell) = (getpwnam($F[2]))[6,7,8]) {$_ .= ",$fullName,$Dir,$Shell"}' gtc_members.txt
所有/etc/passwd
条目都可以通过
perl -E'$,=":";say @a while @a = getpwent()'
答案 1 :(得分:1)
确实更好地使用getpw*
函数来获取系统用户数据,但如果你坚持阅读/ etc / passwd,那么使用以下策略:
@userNames
数组。$userName
查找,如果存在 - 从存储/ etc / passwd数据的散列中推送数组。这个例子并没有发明任何新内容,但无论如何我都要说。注意:最终数组@ userNames_1在第二次循环的evey迭代时重置。假设你在第二个循环中做了一些事情。全部放入大阵列是没用的恕我直言。但如果需要,请在my
之后立即删除push
,并且不会重置。 $userName
在词法上是while
循环块的本地,因此使用相同的名称。此外,我正在获取匿名数组作为参考,因为取消引用它@{$hash{$index}}
给我“未初始化的值”错误。不确定它是否非常正确,但无论如何都可以。
open PASSWD, "</etc/passwd" or die "$!";
open INFO, "<gtc_members.txt" or die "$!";
my %pwhash;
while (<PASSWD>) {
chomp;
my ($userName, $fullName, $homeDirectory, $shell) = (split /:/)[0, 4, 5, 6];
$pwhash{$userName} = [$fullName, $homeDirectory, $shell];
}
while (<INFO>) {
chomp;
my ($userName, $userAddress, $userEmail, $userManager) = (split /,/)[2, 3, 4, 6];
push my @userNames_1, ($userAddress, $userEmail, $userManager);
push @userNames_1, (@$pwinfo) if ($pwinfo = $pwhash{$userName});
# test printout
print join(',', @userNames_1), "\n";
}
答案 2 :(得分:-1)
试试这个:
use Data::Dumper;
use strict;
use warnings;
my %users_in_passwd;
while (<PASSWD>) {
chomp;
my $userName = (split ":", $_)[0];
my $homeDirectory = (split ":", $_)[5];
my $fullName = (split ":", $_)[4];
my $shell = (split ":", $_)[6];
$users_in_passwd{$userName} = [$fullName, $homeDirectory,$shell];
}
while (<INFO>) {
chomp;
my $userName1 = (split ",", $_)[2];
my $userAddress = (split ",", $_)[3];
my $userEmail = (split ",", $_)[4];
my $userManager = (split ",", $_)[6];
if (exists $users_in_passwd{$userName}){
my @data_in_passwd = @{$users_in_passwd{$userName}};
print Dumper($userName,$userName1,\@data_in_passwd,);
### do something
}
}