Re: Need help with comparison code
by roboticus (Chancellor) on Feb 02, 2011 at 17:36 UTC
|
sowais:
Add a chomp after reading the file from <IN>. The line terminator will prevent the filename from matching. Kind of like "foo" and "foo " are different.
...roboticus
When your only tool is a hammer, all problems look like your thumb.
| [reply] |
Re: Need help with comparison code
by Anonymous Monk on Feb 02, 2011 at 17:38 UTC
|
Lets get the basics that a lot of people will mention out of the way up front:
Perl should then tell you about how there is no function (& vs $) called "outfile", among other things
Also my $file = @files is probably not going to do what you want. Array in scalar context gives the count of items in the array.
| [reply] [d/l] [select] |
Re: Need help with comparison code
by wind (Priest) on Feb 02, 2011 at 18:20 UTC
|
From as I understand your description, you want one file to be a running list of the new files that have arrived in the directory, while the second file will be a list of just the new ones at that moment. If this is the case, then the following will probably get you what you want.
#!/usr/bin/perl
use strict;
use warnings;
# emailsent.txt-will contain the name of all files for whom an alert h
+as been sent
# emailtogo.txt-will contain the name of all new files for whom an ale
+rt has to be sent
my $matchfile = 'emailsent.txt';
my $outfile = 'emailtogo.txt';
##########################
my $directory = 'C:\';
opendir(DIR, $directory);
my @files = grep { $_ ne '.' && $_ ne '..' } readdir DIR;
closedir(DIR);
# storing all file names in the folder in an array
foreach(@files){
print $_,"\n";
}
# Build list of old files for comparison
open my $ih, '<', $matchfile or die "Can't open file, $matchfile: $!";
my %oldFiles = map {chomp; $_ => 1} <$ih>;
close $ih;
# Append new files to total list
open my $oh_tot, '>>', $matchfile or die "Can't open file, $matchfile:
+ $!";
open my $oh_new, '>', $outfile or die "Can't open file, $outfile: $!";
# Comparing the array to the names in $matchfile
foreach my $file (@files) {
if (! $oldFiles{$file}) {
print $oh_tot "$file\n";
print $oh_new "$file\n";
}
}
close $oh_tot;
close $oh_new;
- Miller | [reply] [d/l] |
|
|
Thanks alot! your code was very helpful. I had to make some minor changes but I think I'll get it working. As you know I am a beginner in Perl, could you recommed any resources where i could learn some more on how to program in Perl. I know this site is great in getting help on code already written but want to learn how to write properly first.
| [reply] |
|
|
The biggest and most helpful resource for any perl programmer independent of experience is perldoc. The more time you spend there and are familiar with all of the faqs and documentation, the better off you'll be.
The second resource you'll need is cpan for all of the code provided by other perl experts for use by others.
After that, the best resources are subjective, as there are lots of books out there and some are favored more than others depending on the programmer. If you're looking for ways to have good style, then I might suggestion Damian Conway's Perl Best Practices book. It's been out a while, but definitely stilly has some good tips.
Good luck,
- Miller
| [reply] |
Re: Need help with comparison code
by Gulliver (Monk) on Feb 02, 2011 at 18:47 UTC
|
Since you're using Windows I recommend you use Notepad++ or a similar programmers editor since it will help with closing brackets and parenthesis.
Also, you are likely to run into problems comparing strings with eq since filenames can have upper and lower case. Either use matching with the case insensitive modifier '//i' or 'm//i', or use the lower case function, lc(), before the compare.
use strict;
use warnings;
my @files = ( 'file1.txt', 'a.exe', 'my.log');
my @files2 = <DATA>;
foreach(@files){
my $regex=$_;
$regex =~ s/\./\\\./; # replace the '.' in file.ext
# with '\.' so it will work in the match.
print "\n\tuse $regex as the regex\n";
foreach my $file2(@files2){
chomp $file2;
print "---", $file2, "\n";
if ($file2 =~ /$regex/i){
print "\tmatched with //i...\n";
if ($file2 ne $_){
print "\tbut not with string compare.\n";
} else {print "\tand with string compare.\n";}
}
}
} #this one was missing
__DATA__
File1.txt
A.exe
B.ext
my.log
updated; fixed some goofy bugs | [reply] [d/l] |
Re: Need help with comparison code
by GotToBTru (Prior) on Feb 02, 2011 at 18:16 UTC
|
You have opened both IN and OUT using the same mode. You probably mean:
open IN,'<',$matchfile or die "Could not open $matchfile\n";
open OUT,'>>,$outfile or die "Could not open $outfile\n";
Foreach syntax: foreach $var (@array)
For syntax: for (expression; condition; control)
I think you want to use two foreach commands here:
foreach my $file (@files) {
foreach my $file2 (<IN>) {
| [reply] [d/l] [select] |
|
|
for/foreach (<$fh>) is generally a bad idea - it implies slurping the file and creating a list of lines internally. Better is to use a while (<$fh>) loop. In both cases the loop body handles things a line at a time, but while is a better semantic match and is likely to be much more memory (and possibly slightly more time) efficient.
True laziness is hard work
| [reply] [d/l] [select] |
|
|
| [reply] |
Re: Need help with comparison code
by sowais (Sexton) on Feb 08, 2011 at 17:41 UTC
|
Hello Everyone! Thank you for all the help you guys had provided. With your help I have come up with a decent version but one that is still not giving me the output i want. I need help with the bottom part of the code where I am comparing the array with the hash. I am comparing the and two and wherever it doesnt match I am printing that to a text file. Please help! have been trying to accomplish on this on my own but no luck.
Thanks!
#!/usr/bin/perl
use strict;
use warnings;
# emailsent.txt-will contain the name of all files for whom an alert h
+as been sent
# emailtogo.txt-will contain the name of all new files for whom an ale
+rt has to be sent
my $matchfile = 'emailsent.txt';
my $outfile = 'emailtogo.txt';
my $directory = 'C:\Perl';
opendir(DIR, $directory);
my @files = grep { $_ ne '.' && $_ ne '..' } readdir DIR;
closedir(DIR);
# storing all file names in the folder in an array
foreach(@files){
print $_,"\n";
}
# Build list of old files for comparison
open my $ih, '<', $matchfile or die "Can't open file, $matchfile: $!";
my %names = map {chomp;} <$ih>;
close $ih;
open my $oh_tot, '<', $matchfile or die "Can't open file, $matchfile:
+$!";
open my $oh_new, '>', $outfile or die "Can't open file, $outfile: $!";
# Comparing the array to the names in $matchfile
foreach my $file (@files) {
if (! $names{$file}) {
print $oh_new "$file\n";
}
}
close $oh_tot;
close $oh_new;
| [reply] [d/l] |
|
|
#!/usr/bin/perl
use strict;
use warnings;
# emailsent.txt-will contain the name of all files for whom an alert h
+as been sent
# emailtogo.txt-will contain the name of all new files for whom an ale
+rt has to be sent
my $matchfile = 'emailsent.txt';
my $outfile = 'emailtogo.txt';
my $directory = 'C:\Perl';
open(INPUT,">emailtogo.txt");
close(INPUT);
# storing all file names in the folder into an array
opendir(DIR, $directory);
my @files = grep { $_ ne '.' && $_ ne '..' } readdir DIR;
closedir(DIR);
foreach(@files){
print $_,"\n";
}
# Build list of old files for comparison
open my $ih, '<', $matchfile or die "Can't open file, $matchfile: $!";
my @names = <$ih>;
close $ih;
chop @names;
foreach(@names){
print $_,"\n";
}
open my $oh_tot, '+>>', $matchfile or die "Can't open file, $matchfile
+: $!";
open my $oh_new, '+>>', $outfile or die "Can't open file, $outfile: $!
+";
# Comparing the array to the names in $matchfile
for $a (@files) {
my $found = 0;
for $b (@names) {
$found = 1 if $a eq $b;
}
print $oh_new "$a\n", if !$found;
print $oh_tot "$a\n", if !$found;
}
close $oh_tot;
close $oh_new;
| [reply] [d/l] |