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 Wanet Telecoms Ltd on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Reading input from 2 files

Status
Not open for further replies.

PerlNoob2005

Programmer
Feb 7, 2005
2
US
Hi all, I am new to the Perl language and am seeking guidance from you all :) I am trying to write a fairly simple program, but I am running into difficulty due to my lack of tips and tricks of the language. I wish to read line by line from 2 input files (and one file may be larger or smaller than the other) and concatenate the strings located on these coinciding lines. If one input file is shorter than the other, then the concatenation is only to include the 1 line. Here is what I have so far:

#!/usr/bin/perl -w

unless(@ARGV)
{
print "usage: test.pl argument\n";
exit;
}

$file1 = $ARGV[0];
open (IN1, $file1);

$file2 = $ARGV[1];
open (IN2, $file2);

while ($DNA1 = <IN1> && $DNA2 = <IN2>)
{
$Concat = $DNA1.$DNA2;
print "HERE: $DNA1 $DNA2 \n Concatenation: $Concat \n";
}

$input3 = $ARGV[2];
print "$input3";

close IN1;
close IN2;


The above code gives me an error with the && operation. I am unsure as to how to continue reading from both input files at the same time, while one may be shorter than the other. Any tips or advice would be great. Thanks!
 
1. && isn't the correct operator for this. From your description, "If one input file is shorter than the other, then the concatenation is only to include the 1 line," it sounds like you want to continue reading from the 2 files as long as there's input available from either one. && would quit as soon as you reached the end of the shorter file. So you want to do an or, not an and. So it would seem that || is what you should be using. There's a problem with this, however.

2. && and || have higher precedence than the assignment operator =. So
while ($DNA1 = <IN1> || $DNA2 = <IN2>)
won't be evaluated the way you might expect. This is why you're getting the error message, "Can't modify logical and (&&) in scalar assignment."

3. There are a few ways around this:
a. Enclose the 2 assignments in parentheses, i.e.
while (($DNA1 = <IN1>) || ($DNA2 = <IN2>))
b. Use the lower-precedence or operator
instead of ||
c. Use the comma operator (,) instead of
||

Another point: the lines in your input files contain line-termination characters, which differ by operating system. You need to remove these for your output to look the way you want. Use chomp for this, e.g.
while ($DNA1 = <IN1> or $DNA2 = <IN2>)
{
chomp ($DNA1, $DNA2);


HTH

 
Hmm, on second thought that might not work quite the way I thought. You're probably better off doing this:
Code:
$DNA1 = <IN1>;
$DNA2 = <IN2>;
while ($DNA1 || $DNA2) 
{ 
  chomp ($DNA1, $DNA2);
  $Concat = $DNA1.$DNA2;
  print "HERE: $DNA1 $DNA2 \n Concatenation: $Concat \n";
  $DNA1 = <IN1>;
  $DNA2 = <IN2>;
}
Sorry if I mislead you with that last post.
 
[tt]awk -f file1 file2[/tt]
Code:
BEGIN { file2 = ARGV[2]; ARGC--
  while ( getline + (getline DNA2 <file2) > 0 )
  { concat = $0 DNA2
    printf "Here: %s %s\nConcatenated: %s\n", $0,DNA2,concat
    $0=DNA2=""
  }
}
 
Should have been
[tt]awk -f prog.awk file1 file2[/tt]
 
Thank you both very much for the help. Both versions work perfectly, although I may need comments for your code in the future, cntr. It looks quite advanced :)
 
I may need comments for your code in the future, cntr.
Let's say you run the program with
[tt]awk -f prog.awk myfile1 myfile2[/tt]
ARGV is now
["awk", "myfile1", "myfile2"]

[tt]BEGIN { file2 = ARGV[2][/tt]
file2 now is "myfile2"
[tt]ARGC--[/tt]
ARGV is now, in effect,
["awk", "myfile1"]
[tt]while ( getline[/tt]
Read line from "myfile1" and put it in $0.
[tt]+[/tt]
[tt](getline DNA2 <file2)[/tt]
Read line from "myfile2" and put it in DNA2.
[tt]> 0 )[/tt]
The command getline returns 1 on success, 0 on end of file,
and -1 on error. If the sum of the two getlines is >0,
we've got at least one line from one file.
[tt]{ concat = $0 DNA2[/tt]
To concatenate two strings, simply juxtapose them.
[tt]printf "Here: %s %s\nConcatenated: %s\n", $0,DNA2,concat[/tt]
The printf command behaves as it does in C.
[tt]$0=DNA2=""[/tt]
I goofed here. Should have been simply DNA2="".
[tt]}[/tt]
[tt]}[/tt]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top