Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

extract entries from a table based on values in another table 1

Status
Not open for further replies.

gussifinknottle

Programmer
Jan 16, 2001
19
US
Hello,

I have two files that have delimited entries as shown below. I would like to use either Perl script to extract all the rows in File 1 corresponding to values in File 2 and output it to another File.

File 1
-------
1 36 24 Object1
2 45 36 Object2
3 96 21 Object3
4 89 32 Object4
5 98 23 Object5
6 99 21 Object6
7 56 21 Object7

File 2
-------
2 45 36
5 98 23
6 99 21


Thanks,
Gussi
 
Hi,

Something like this should work. I am creating a hash table of input1 (key = what I will check against input2 | value = the full row [what I will output]) etc.

Code:
#! /usr/bin/perl
use strict;
use Cwd;

my $in1_path = getcwd.'/input1.txt';
my $in2_path = getcwd.'/input2.txt';
my $out_path = getcwd.'/output.txt';

my(%output);
open(IN1,"<$in1_path") || die "Cannot Open IN1";
while(my $current1 = <IN1>){
	$current1 =~ /^((\d\s\d\d\s\d\d)\s([A-Za-z0-9]*))/;
	$output{$2}=$1;
}
close(IN1);

unlink($out_path);
open(OUT,">>$out_path") || die "Cannot Open OUT";
open(IN2,"<$in2_path") || die "Cannot Open IN2";
while(my $current2 = <IN2>){
	rem_nl($current2);
	print OUT "$output{$current2}\r\n";
}
close(IN2);
close(OUT);

sub rem_nl{
	$_[0] =~ s/\r$//;
	$_[0] =~ s/\n$//;
	$_[0] =~ s/\r\n$//;
	$_[0] =~ s/\n\r$//;
	return $_[0];
}

Chris
 
A bit cleaner:

Code:
my(%output);
open(IN1,"<$in1_path") || die "Cannot Open IN1";
while(my $current1 = <IN1>){
	$current1 =~ /^((\d\s\d\d\s\d\d)\s([A-Za-z0-9]*))/;
	$output{$2} = $1;
}
close(IN1);

unlink($out_path);
open(OUT,">>$out_path") || die "Cannot Open OUT";
open(IN2,"<$in2_path") || die "Cannot Open IN2";
while(my $current2 = <IN2>){
	$current2 =~ /^(\d\s\d\d\s\d\d)/;
	print OUT "$output{$1}\r\n";
}
close(IN2);
close(OUT);

Chris
 
Hi Chris,

When I ran this with a test case, it ran fine and give me the output I was looking for. However, when I changed the \d to a regular expression, ([0-9]*), to include search for numbers that may go from 1 to abut 100k, I don't see any output.

Thanks,
Gus
 
Try \d+ instead of [0-9]*

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Whilst debugging the regex it may be a good idea to print $2 within the first while loop (IN1) and $1 within the second (IN2) because these are the 2 values that are being compared. If they don't match (IN2 key doesn't exist in hash table) then an empty line is outputted.

Chris
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top