Mimi Cafe wrote: > I am trying to compare one or more lists against a master record file and > find out elements of the master record which are not in the other records > and compile new lists of elements which are in the master data, but not > found in the other records. > > This works to fine, but the output list is random to some extend. The script > is run with command line arguments specifying the master data file and the > other file(s) to compare: > > script --master masterrecord.txt --compare compare_file1 --compare > compare_file2
I'm not sure what your question is, or what you mean by 'the output list is random'. But I can comment on your code. > ########################################## > > #!c:\perl\bin\perl.exe -w The #! line is only noticed by Unix-type shells and is ignored completely on a Windows platform, so it's best just to leave it off. (Perl itself still takes note of the command line switches specified here and so still actions your -w, but see below.). > use strict; > #use warnings; It's always better to use warnings; rather than using the -w command-line switch. > #use diagnostics; > use Getopt::Long; > > # Perl script to compare WSUS and AV clients against AD computers and create > a report of AD > # computers not found in the WSUS or AV list. > > use constant DEFAULT_REPORTDIR => 'CompareReport'; > #use constant DEFAULT_WORKINGDR => '.'; > my ($master, @compare, $help); > > > Getopt::Long::Configure ("permute","ignorecase"); > > GetOptions( > "master=s" => \$master, > "compare:s" => [EMAIL PROTECTED], > "help|?!" => \$help, > ); > > usage() if $help; > > foreach (@compare){ > die "File $_ does not exist or it's empty. Please check the file try > again.\n" unless -s $_; > } If your die string ends with a newline then the output won't include the source file and line number, which may be useful when you are debugging. Like this die "failed"; produces failed at E:\Perl\source\x.pl line 14. while die "failed\n"; produces just failed > my $outputdir = DEFAULT_REPORTDIR; > unless (-d $outputdir){ > mkdir ($outputdir) or die "could not create dir for $outputdir: $!\n"; > } mkdir will only succeed if the parent directory exists. That is to say, mkdir 'path/to/my/directory'; will fail unless path/to/my exists. It may be useful to take a look at the mkpath function in File::Path, which will also create any intermediate directories in the path. > # Read the master list and populate our array. > open (MASTERFILE, "<", $master) or die "Could not open $master for reading: > $!\n"; > my @master_clients = <MASTERFILE>; > chomp(@master_clients); > close MASTERFILE; It is better to use lexical file handles, as in open my $masterfh, '<', $master or die "Could not open $master for reading: $!"; If I was writing this I would say my @master_clients = do { open my $fh, '<', $master or die "Could not open $master for reading: $!"; <$fh>; }; chomp @master_clients; > my (%inputclient,$list); It is always best to declare variables as close as possible to the point of use. Declaring %inputclient here means that the contents the files in @compare will be accumulated to the hash, and when you are processing the last file in the list your output will show only those values that are in /none/ of the files in the list. Is this what you mean by the output list being random? I'm fairly certain that you want a per-file report, ans so the hash should be declared within this for loop. > # Read the other files and compare the content to the master client list. > foreach $list (@compare){ foreach my $list (@compare) { > # Output file name set of element curerently processed. > # Open file to read from. > > open(INFH, "$list") or warn "Could not open $list for reading: $!\n"; This will give you a warning but still continue to use an invalid file handle. > while (<INFH>){ > chomp; > $inputclient{"$_"} = $_; > } > close INFH; { open my $fh, '<', $list or do { warn "Could not open $list for reading: $!"; next; }; while (<$fh>) { chomp; $inputclient{$_}++; } } > my $outputfile = $list; > my (@missing_clients, %outputclient); > > foreach my $aditem (@master_clients){ > push (@missing_clients, $aditem) unless exists $inputclient{"$aditem"}; > } > > > open (OUTPUTFILE, ">$outputdir\\$outputfile") || die "Could not open > $outputfile: $!\n"; > foreach (@missing_clients){ print OUTPUTFILE "$_\n";} > close (OUTPUTFILE); { open my $fh, '>', "$outputdir\\$list"; print $fh "$_\n" foreach @missing_clients; } > } > > > # Subroutine to print example of script usage. > > sub usage { > print "\nUSAGE:\t$0 --master master_file --comapre file1 --comapre > file2\n\n"; > print "\tExample: $0 --master adlist --compare avlist --comapre file2\n"; > print "\t$0 --help or --? should displays this usage summary.\n"; > exit; > > } HTH, Rob -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/