de2425 has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have two files with a great deal of data. The two files have a common alpha-numeric field and one of the files has a numeric field that is associated with the common alpha-numeric field. I would like to search the file with both values and return a version of the file missing the numeric field that has the numeric field and the alpha-numeric field. Each number corresponds to a particular alpha-numeric field. I cannot figure out how to make this happen. I have tried splitting the arrays and comparing the two with an if statement but I either get no results or undesirable ones. Would someone be able to help me with this? Thank you so much in advance. Also, this is the code that I tried. Sorry that I didn't include it earlier. It obviously has some problems. I'm just not sure how to go about correcting them.

!#/usr/bin/perl -w open (IN, "C:/work/job2/Ab2SigmaGene.txt"); while (<IN>){ #start while loop chomp; @t=split(/\t/,$_); $t[4]= $AB{[4]}; } #end while loop close IN; open (OUT, ">C:/work/job2/XP725a.txt"); open (IN, "c:/work/job2/XP725_Ab_array.txt"); while (<IN>){ #start chomp; @var1=split(/\t/,$_); if ($var1[2] and exists $Ab{$var1[2]}){ print OUT "$var1[0]\t$var1[1]\t$var1[2]\t$AB[4]\n";} } #end close IN; close OUT;

Replies are listed 'Best First'.
Re: Compare Arrays, Return Values
by broomduster (Priest) on Aug 28, 2008 at 14:35 UTC
    I would like to search the file with both values and return a version of the file missing the numeric field that has the numeric field and the alpha-numeric field.
    That statement is giving me a headache. ;-)

    Please provide samples of the two files and a sample of what you want the final output to look like and the code that you tried but are having trouble with. Then it will be easier for folks here to help you.

    Also see How do I post a question effectively?.

      I'm very sorry for any confusion. I realize that I probably was not succinct in my posting. An example of the data from the first file would be:

      Product # Prod Name Univers ID

      A101 something 123

      A102 else 456

      A103 it 789

      A104 the 012

      An example of data from the second file would be

      Product # Product Name Univers ID

      A102 else

      A103 it

      An example of the file that I want to generate would be:

      Product # Product Name Univers ID

      A102 else 456

      A103 it 789

      Does this make more sense? Again, I apologize for not being more clear. I'm an obvious perl novice and am trying to get my head around the language. Any help would be greatly appreciated.

Re: Compare Arrays, Return Values
by gone2015 (Deacon) on Aug 28, 2008 at 14:37 UTC

    Sounds as if you want to use a hash.

    Read the both-values-file and construct a hash whose keys are the alpha-numeric field and the values are the numeric field. Process the other file against the hash and write to the result file.

    Tricky, huh ? Or have I missed something ?

      That's about the sum of it. I just am at a complete loss for what to do.

        OK. Well, first use: (a) use strict; (b) use warnings; (c) my variables.

        Now, in your input loop you have:

        @t = split(/\t/, $_) ; $t[4]= $AB{[4]} ;
        which is a horrible mess :-( What you want to do is:
        $AB{$alpha_numeric_field} = $numeric_field ;
        where the two fields are elements of @t, I cannot tell which.

        The output process contains:

        if ($var1[2] and exists $Ab{$var1[2]}) { print OUT "$var1[0]\t$var1[1]\t$var1[2]\t$AB[4]\n" ; }
        which looks as though it would be OK, but for $AB[4], which ought to be $AB{$var1[2]}. (Oh. And it should be $AB{...} in the if !).

        use strict would have picked up the $Ab{} mistake (undefined hash %Ab) and the use of $AB[4] (undefined array @AB). It would not, however, have picked up $AB{[4]}, which is the kind of honest-to-goodness inscrutability that Perl is justly famous for, and which one grows to be deeply fond of.

        BTW, rather than:

        @var1 = split(/\t/,$_) ;
        you can write (for example):
        ($field_name, $other_field, $further_field, ...) = split(...) ;
        then you have each field in a variable with a meaningfull name -- more friendly than $var1[2] etc.

        I don't mean to be rude, but you've just described the problem. How can you be at a loss as to what to do?

        Open file 1
        • For each record in file 1
          • break the record into fields
          • update a hash using Product Number and Produce Name as the keys, with a value of Univers ID

        Open file 2
        • For each record in file 2
          • break the record into fields
          • Is there a hash with Product Number and Produce Name as the keys?
            • If so, write out the keys and the value
Re: Compare Arrays, Return Values
by derby (Abbot) on Aug 28, 2008 at 14:43 UTC
Re: Compare Arrays, Return Values
by dwm042 (Priest) on Aug 28, 2008 at 15:26 UTC
    Some comments about your code:

    1) If Grandfather hasn't told you by now, someone else surely will, but you need to use strict; and use warnings;

    2) The hash element $AB{$foo} (on lines 8 and 21) is not the same as $Ab{$foo} (on line 20).

    3) Your program is either a fragment or else you have forgotten to add data to the $AB/$Ab hash.

    4) oshalla is dead on when he suggests a hash.

    Let's see if we can make a working example of using a hash. We'll fudge opening two files by loading our "file1" and "file2" with a DATA statement and then using modal behavior to handle both files.

    #!/usr/bin/perl use warnings; use strict; my $mode = "start"; my %hash; while(<DATA>) { chomp; if ( $_ =~ /file1/) { $mode = "read"; next; } if ( $_ =~ /file2/) { $mode = "add"; next; } if ( $mode eq "read" ) { $hash{$_} = 0; } elsif ( $mode eq "add" ) { my ( $key, $value ) = split " ", $_, 2; $hash{$key} = $value if ( exists($hash{$key}) ); } } for ( sort keys %hash ) { print "$_ => $hash{$_} \n" if $hash{$_}; } __DATA__ file1 Angel Baker Candy Edward Fox file2 Angel 7 Fox 10 Gigantic 29 Candy 3
    And the results are:

    C:\Code>perl order_by_key.pl Angel => 7 Candy => 3 Fox => 10
Re: Compare Arrays, Return Values
by Zenshai (Sexton) on Aug 28, 2008 at 14:35 UTC
    Can you give an example? Maybe its just me, but I have no idea what you're talking about.

    Update: Ok so its not just me, I feel better. :)
      I'm very sorry. I didn't really know how to state what I was wanting to do clearly enough.