ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am having some trouble getting a nested loop to work properly in Perl (ActiveState 5.7.8)
I have two files filled with numbers. File1 and File2.
I need to check if every value from File1 occurs in File2.
The best method seemed to take a line from File1, make an array, split it and get the number.
Once i have this number i want to start a loop, to go through File2, to look for an occurence of this number.
As i'm typing this i'm thinking there must be more than one way to do it, but i wouldn't know how.
The most logical answer would be to place some extra {} around the second loop, but unfortunately this gives the same result.
I also have tried different loops (while and for) but i can't get it to work.
I am getting this as a result:
File1 File2
1 1
2 2
3 3
4 4
Buit what i want is this :
File1 File2
1 1
1 2
1 3
1 4
and the next :
File1 file2
2 1
2 2
2 3
2 4
If someone can please help me i'd be very thankfull. I have been at it all day and i am really out of options here.
#!/usr/bin/perl -w
my %one_lines;
my %two_lines;
open(FILE, "<one") || die "can't open file one : $!\n";
while (<FILE>) {
chomp;
$one_lines{$_} = 1;
}
close(FILE);
open(FILE, "<two") || die "can't open file two : $!\n";
while (<FILE>) {
chomp;
$two_lines{$_} = 1;
}
close FILE;
foreach my $value (keys %one_lines) {
if ( ! defined( $two_lines{$value} ) ) {
print "$value exists in file one but not file two\n";
}
else {
print "$value exists in file one AND file two\n";
}
}
The dis-advantage is that you lose the ordering of the lines from file one - the keys %hash function doesn't return the keys in the same order they were added.
Thank you for your (very fast) response.
I see that i have much to learn about hashes.
The goal is to see what numbers from file1 occur in file2. The numbers that do not occur in file2 should be written to a 'trashfile' that i can send back to the person who delivered the data to me.
I'll have to dive into it in order to understand your answer.
As soon as i discover what actually is happening and tested it, i'll let you know if it worked.
The reason i used the arrays, is that it enabled me to read the files line by line.
File 2 contains 17000 lines, and i didn't know if i could fit it all into 1 variable/hash/map/array/string.
Nonetheless thank you, i'll have a go at it and let you know.
You could still use a hash if you wanted to read only one file into memory. The advantage of using a hash for this is that if you have repeated numbers in the set, you only use one element of a hash.
For example if the file contains
Code:
1
1
1
2
2
4
4
4
4
4
...then the hash will only contain three keys: 1, 2, and 4, whereas an array would contain ten items.
Here's a re-written script which only holds one of the file's sets in memory at once (file "two")
Code:
#!/usr/bin/perl -w
use strict;
my %two_lines;
open(FILE, "<two") || die "can't open two : $!\n";
while(<FILE>) {
chomp;
$two_lines{$_} = 1;
}
close(FILE);
open(FILE, "<one") || die "can't open one : $!\n";
while(<FILE>) {
chomp;
if ( defined($two_lines{$_}) ) {
print "value $_ from one exists in file two\n";
}
else {
print "value $_ from one DOES NOT exist in file two\n";
}
}
close(FILE);
I'd toss some scope into this as well - a few my's to keep things from carrying over to the next iteration. otherwise all of this risks running in global scope, at which point you've got the chance of an element not getting updated the way you expect it to.
At the moment the script is doing what it's supposed to do.
According to most programming tut's using the 'my' would indeed be a sensible thing to do. I don't know if it's really usefull with tiny scripts like my own, but it can prevent nasty errors.
Especially the hash-function i learned turned out to be very usefull.
#!/usr/bin/perl -w
use strict; # Enforce declarations
in all progs, even temp test ones. Prevents you from thinking something works when in fact it relies on globals and side effects.
Incidentally, you may see
use warnings;
after use strict; instead of the '-w' flag.
Perl Best Practices offers a collection of 256 guidelines on the art of coding to help you write better Perl code--in fact, the best Perl code you possibly can. The guidelines cover code layout, naming conventions, choice of data and control structures, program decomposition, interface design and implementation, modularity, object orientation, error handling, testing, and debugging.
One can easily make a template that contains the skeleton of a perl script with all the boilerplate that a person desires already coded in ... cheers, makyo
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.