perl - 比较文件并检查一个文件中存在的东西在另一个文件中是否不存在
问题描述
我有两个文件,一个包含所有活动用户登录名,另一个包含活动用户文件中不再存在的用户登录权限,所以我想比较这些并过滤掉不再存在的用户名,但我不知道如何开始。我已经从两个文件中过滤掉了用户名,它们位于两个单独的数组中。这是我的整个代码,警告,它包含我需要程序执行的其他内容,就像它不存在一样。还有警告,不要担心评论,它是德语,只有我知道什么做什么。
#!/usr/bin/perl
use strict;
#use warnings;
use utf8;
use Data::Dumper;
my $usernames = 'usernames.txt';
my $permissions = 'ab1000.prm';
my $prmlogins = 'prmlogins.txt';
# Programme ausführen
clean_permissions();
# Subroutinen
# Subroutine welche die gewünschte Datei Zeile für Zeile ausgibt
sub read_lines {
my($file) = @_;
open my $in, "<:encoding(utf8)", $file or die "$file: $!";
local $/ = undef;
my $content = <$in>;
close $in;
return split /\n/, $content;
}
sub clean_permissions {
my $counter = 0; # Zählervariable wird definiert
my @adnutzer = ''; # Array für Nutzernamen wird definiert
my @ab1000prm = read_lines('ab1000.prm'); # Zeilen des Dokuments werden eingelesen
my @adnames = read_lines('ad_user.csv'); # Zeilen der CSV mit Subroutine in Array einlesen
my $zeilenzaehler = 1; # Zeilenzähler wird definiert
my $zeilen = ''; # Variable in der die Anzahl der Zahlen gespeichert werden
my @prmnutzer = '';
foreach(@adnames) { # Über das erstellte Array itirieren
$counter++; # Zähler für Zeilenanzahl
next if ($counter eq 1); # Erste Zeile überspringen
my @tmp = split(';', $_); # Spalten am Semikolon trennen
push(@adnutzer, uc($tmp[3])); # Vierte Spalte (Userlogins) in Array pushen
}
foreach(@ab1000prm) { # Über die Permissions datei itirieren
my $wortzaehler = length($_); # Variable zum Zählen von Zeichen in einer Zeile
$zeilen = $zeilenzaehler++; # Zeilenzähler wird der Zeilen Variable zugewiesen
if ($wortzaehler > 255) { # Wenn eine Zeile mehr als 255 Zeichen hat:
#print ("Zeile $zeilenzaehler behinhaltet: $wortzaehler zeichen!\n"); # Wird die Nummer der Zeile und die Anzahl and Zeichen ausgegeben
}
next if /^#/; # Zeilen mit '#' werden übersprungen
my @tmp = split(":", $_); # Übrigen Zeilen werden am ':' getrennt und in temporäres Array gepackt
@prmnutzer = split(",", $tmp[1]); # Der wichtige Teil der Zeilen wird in Array gepackt
}
#print("Das Dokument beinhaltet: $zeilen Zeilen!\n"); # Anzahl der Zeilen wird ausgegeben
}
权限文件如下所示:
##
!*EDIT.FIRMA.FIR_BELEGNR_007:
## Sperrt im Einkauf das Editieren des ursp. Bestelltermins
!*EDIT.POSITIONEN.POS_TERM2:
##
!INFOPT*ARTSTAT.AST_BSTWERT:EDV,EK,EKL,GF,KSLMITEK,VT,EKIWE,EKTEC,KSIWE,EKHOT
## SperrtdieStammdateninderArtikelverwaltung.
ART_VERW*M0805.1:
##
!*EDIT.EINKVERBAND.EKV_X_SZBNR:KATEI,EDV,MHERGEN,CJANSSENS
## SperrteditierenvobRabattB-ArtikelimKunden
!*EDIT.KUNDEN.KDN_GRRAB_002:EDV,MGREB,JEIFERT,CJANSSENS,RWAUMANS,NWACHALL
用户名列在“:”之后,之前的所有内容都无关紧要。
活动用户文件如下所示:
FAX800
LABDELHALIM
DABEL
LABU
UACKERMANN
DADAEM
CADLER
SADOLF
FAFF
KAGOCS
JAHLHEIM
JAIGNER
KAIZELKSNIS
NAKGUEN
DALAERTS
JALBERS
SALBERT
SALBERTSILA
FALBERTS
SALBRECHT
AALEX
MALGAC
BALLES
YALTUNTAS
SAMBERG
KAMESEDER
BAMLING
CAMLUNG
UAMSUESS
KANDERS
MANDRAE
AANDRAE
GAND
AANTO
EAPPEL
AAPPEL
AAPPELWILPEG
BAPTOULACH
这只是一个片段,该文件有大约 2000 行......
如果相关的话,我也会在 Mac OS 上进行编辑。
附言。我对 Perl 和一般编程真的很陌生:D
解决方案
请参阅以下代码片段以了解解决问题的可能方法。
将活跃用户读入数组并返回数组引用
将权限用户读入数组并返回数组引用
使用活跃用户创建哈希
通过权限用户并查看用户是否处于活动状态
- 如果用户不活跃,将他的 id 保存到“users_ceased”数组中
将“users_ceased”的内容输出到控制台
笔记:
根据您的设置调整文件名,输入的数据和格式保留从发布
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my $debug = 1;
my $fn_users = 'data_active_users.dat'; # File with active users
my $fn_perms = 'data_permission.dat'; # File with permissions
my $users_act = read_users($fn_users); # Read active users
my $users_perm = read_perms($fn_perms); # Read permission users
say Dumper($users_act) if $debug;
say Dumper($users_perm) if $debug;
my %active;
my @users_ceased;
$active{$_}++ for @{ $users_act }; # Fill hash with active users
for my $user ( @{ $users_perm } ) {
push @users_ceased, $user if not $active{$user};
}
say '
Ceased users
-----------------------------';
say for @users_ceased;
sub read_users {
my $filename = shift;
open my $fh, '<:encoding(utf8)', $filename
or die "Couldn't open $filename";
my @users = <$fh>;
close $fh;
chomp @users;
return \@users;
}
sub read_perms {
my $filename = shift;
my @users;
open my $fh, '<:encoding(utf8)', $filename
or die "Couldn't open $filename";
while( <$fh> ) {
next unless /.*?:(.*)/;
my $list = $1;
next if not defined $list;
my @add_users = split ',', $list;
@users = (@users, @add_users);
}
close $fh;
return \@users;
}
输出
Ceased users
-----------------------------
EDV
EK
EKL
GF
KSLMITEK
VT
EKIWE
EKTEC
KSIWE
EKHOT
KATEI
EDV
MHERGEN
CJANSSENS
EDV
MGREB
JEIFERT
CJANSSENS
RWAUMANS
NWACHALL
稍作代码修改
my %active;
my %users_ceased;
$active{$_}++ for @{ $users_act }; # Fill hash with active users
for my $user ( @{ $users_perm } ) {
$users_ceased{$user}++ if not $active{$user};
}
say '
Ceased users
-----------------------------';
for my $user ( sort keys %users_ceased ) {
printf "%-10s => %2d time(s)\n", $user, $users_ceased{$user};
}
输出将如下
Ceased users
-----------------------------
CJANSSENS => 2 time(s)
EDV => 3 time(s)
EK => 1 time(s)
EKHOT => 1 time(s)
EKIWE => 1 time(s)
EKL => 1 time(s)
EKTEC => 1 time(s)
GF => 1 time(s)
JEIFERT => 1 time(s)
KATEI => 1 time(s)
KSIWE => 1 time(s)
KSLMITEK => 1 time(s)
MGREB => 1 time(s)
MHERGEN => 1 time(s)
NWACHALL => 1 time(s)
RWAUMANS => 1 time(s)
VT => 1 time(s)
推荐阅读
- java - Java hibernate SQL Null 点异常
- angular - 在异步中使用 Promise 时捕获 HTML5 FileReader 的结果
- javascript - 获取 beforeEach 以仅在它所在的文件中运行测试
- google-apps-script - Google Apps 脚本中对话窗口中的动态文本框
- ifc - BimServer 1.4 getModel 总是返回一个空模型
- node.js - Firebase Admin FCM 发送消息不起作用
- python - 用于python 3的国家仪器pyDAQmx
- matlab - 修改 x 轴标注 (Matlab)
- c# - 带有接口类型键的字典,获取实现接口的键
- android - 正在调用 getResources().getString(
, params) 内部循环会降低性能