Re: Comparing files
by davido (Cardinal) on Jul 19, 2004 at 22:15 UTC
|
One way to do it would be to read each file, pulling out the mac addresses, and then use the mac addresses as hash keys. Something like "$found{$addr}++". Once you've done that, having read each file, %found will contain a list of all mac addresses, and a count for each address. If count == 30, you know that particular address was found in all 30 files, and you can output that key to your new file.
Hope that helps...
If none of this makes sense, start with a less ambitious project, such as reading "Learning Perl" (the Llama book), published by O'Reilly and Associates.
| [reply] |
|
|
If count == 30, you know that particular address was found in all 30 files...
Almost. If count == 30, you know that the MAC showed up 30 times in the combined input. Could've been 30 times in the first file. If, however the OP knows that the MACs are unique within a given file (i.e. each MAC in a file appears only once), then the statement that "count == 30 implies it was found in all 30 files" is true.
| [reply] |
|
|
Good grief. Ok, well, if each file could contain the same mac address more than once, use a second hash to guarantee uniqueness per file. Or another approach would be to start with file one. Put all of its mac addresses into a hash, as keys. Then open file two. Delete any hash keys that aren't found in file two. Open file three. Delete any remaining hash keys that aren't found in file three. And so on... you get the idea. What's left at the end is your list of mac addresses that exist in all 30 files.
| [reply] |
|
|
|
|
|
Re: Comparing files
by shemp (Deacon) on Jul 19, 2004 at 22:19 UTC
|
Lots of gaps to fill in, but this is the basic idea.
my $first_file = pop @all4;
my $master_list = get_all_mac_addresses_from_file($first_file);
foreach my $filename (@all4) {
my $this_list = get_all_mac_addresses_from_file($filename);
foreach my $address (keys %$master_list) {
if ( ! exists $this_list->{$address} ) {
delete $master_list->{$address}
}
}
}
# now $master_list is a hashref whose keys are the
# mac addresses in all the files, so output them
# however you want.
sub get_all_mac_addresses_from_file {
my ($file_name) = @_;
# i dont know what format your files are
# you need to write something to get the names
# out of the files, and return them as the keys
# of a hashref
# The values dont matter.
...
return \%the_list;
}
| [reply] [d/l] |
Re: Comparing files
by graff (Chancellor) on Jul 20, 2004 at 02:10 UTC
|
The first bit (getting the 30 file names) would be easier/better/clearer using a glob (actually your use of qx has a syntax error -- no closing slash or semicolon); and keeping track of MAC values and files that have them is best done with a hash (similar to what davido suggested, but slightly different):
use strict;
my @all_files = </export/home/*_01day>;
# angle brackets around a bareword path pattern returns all matchi
+ng file names
my %macs_found;
for my $path ( @all_files ) {
my $file = $path . ":";
$file =~ s{.*/}{:}; # now it's ":*_01day:"
unless ( open( FILE, $path )) {
warn "open failed on $path: $!\n";
next;
}
while (<FILE>) {
chomp;
$macs_found{$_} .= $file unless $macs_found{$_} =~ /$file/;
}
close FILE;
}
# Now for each mac value, see how many files had it:
my $nfiles = scalar @all_files;
for my $mac ( sort keys %macs_found ) {
if ( split( /::/, $macs_found{$mac} ) == $nfiles ) {
print "$mac found in all $nfiles input files\n";
}
}
(untested) | [reply] [d/l] |
|
|
Your the man, Thanks for your help.
| [reply] |
|
|
Got one more question for you, I have been trying to replace your print "$mac found in all $nfiles input files to print out to a file instead of the screen. I can't seem to get it, I always get some weird type of output: here is what I did.
open(OUT,">$directory") || die couldn't open file:$directory;
print OUT <$mac;
close (OUT);
| [reply] |
|
|
(1) When you post, use <code> to mark the beginning of source code, and </code> to mark the end. Always. (In fact, use it when posting data samples, command lines and anything else where spacing or brackets are important.)
(2) Read the man page description for the "print" function (do "perldoc -f print", or if you're using the docs in html form, browse the "perlfunc" page for the "print" function).
(3) You seem to think that the angle bracket should be used with "print", as if doing redirection (or maybe you learned C++ first?). Anyway, printing to a file handle works like this:
print OUT "string to be printed to outputfile\n";
# or like this:
$outstring = "string to be printed\n";
print OUT $outstring;
Really simple. The only thing that's a little strange is that you don't ever put a comma between the file handle and the stuff to be printed to it.
Update -- one other thing (call it "4") -- just in case you're not clear on this: If you are doing iterations in any sort of loop, and want to print to a file handle on each iteration, be sure to open the file before going into the loop, and close it after the loop. Do NOT open, write and close the file on every iteration. (The format of your question made me worry that this might not be clear.) | [reply] [d/l] |
Re: Comparing files
by McMahon (Chaplain) on Jul 19, 2004 at 22:22 UTC
|
I'd like to know how List::Compare works with 30 lists. It should solve your problem. | [reply] |