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

Hi! I am trying to put the contents of $1 into an array my code as follows:
#open files here my $counter = 0; my @slotarray; while ( <DPSLOTFILE> ) { my $dpdrivloc = "MSL6000 Trinity"; if ( /\Q$dpdrivloc\E:\s*(\d+)/ ) { my $slotarray{$counter} = "$1"; #print OUTFILE "$1"; $counter++; } } for (@slotarray) { print OUTFILE "$slotarray\n"; } #close files here
I'm trying to read the contents of the array and place them into the output file. I keep getting errors when I move things around and try different things. Any ideas are appreciated! Thanks! Ben

edit (broquaint): dropped <pre> tags

Replies are listed 'Best First'.
Re: $1 into an array
by Wonko the sane (Curate) on Mar 25, 2004 at 19:32 UTC
    Hello

    Not running with warnings or strict are ya!
    You are assigning your $1 into the HASH slotarray, but then trying to print out the contents of the ARRAY slotarray.

    # change this line, which assigns into a hash... my $slotarray{$counter} = "$1"; # to something like this, which assigns into an array. push( @slotarray, $1 );

    Wonko
Re: $1 into an array
by jeffa (Bishop) on Mar 25, 2004 at 19:43 UTC
    Not to invalidate Wonko the sane's excellent advice, but try this:
    use strict; use warnings; use Data::Dumper; my @slot; my $dpdrivloc = "MSL6000 Trinity"; my $regex = qr/\Q$dpdrivloc\E:\s*(\d+)/; # ... open DPSLOTFILE ... while ( <DPSLOTFILE> ) { if (my ($numb) = $_ =~ $regex) { push @slot, $numb; } } print Dumper \@slot;

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: $1 into an array
by Enlil (Parson) on Mar 25, 2004 at 19:51 UTC
    Here is some slightly modified code that should work better.
    use strict; use warnings; #open files here #my $counter = 0; my @slotarray; while ( <DPSLOTFILE> ) { my $dpdrivloc = "MSL6000 Trinity"; if ( /\Q$dpdrivloc\E:\s*(\d+)/ ) { #my $slotarray{$counter} = "$1"; #print OUTFILE "$1"; #$counter++; push @slotarray, $1; } } for (@slotarray) { #print OUTFILE "$slotarray\n"; print OUTFILE $_,$/; } #close files here

    The immediate problems i see with your posted code are:  my $slotarray{$counter} = "$1"; which won't work as you cannot put a my when trying to assign to a hash element; which won't work with the my in front of it. So this was changed. Second when you use for (@slotarray){ } you assign each element in @slotarray to $_ which is not the same as $slotarray and hence will print whatever was in $slotarray as many times as there are elements in @slotarray.Note that you could have also done the following:

    for my $slotarray (@slotarray) { print OUTFILE "$slotarray\n"; }

    If you are not going to be using @slotarray for anything other than printing it back out to OUTFILE why not just print while going through the while loop?

    while (<DPSLOTFILE>){ next unless /\QMSL6000 Trinity:\s*(\d+)/; print OUTFILE $1,$/; }
    or this could be reduced to one line: perl -nle 'print $1,$/ if /\QQMSL6000 Trinity:\s*(\d+)/' input_file > output_file;

    -enlil

      I tried what you had stated above and could not get it
      to work.  The file looks like:
      
      Label Location Pool Name Protection [NFK100L2] [MSL6000 Trinity: 1] MSL6000 01/19/2004 [NFK101L2] [MSL6000 Trinity: 5] MSL6000 01/19/2004
      Many times it will only be 1 line long of data but it could be up to three. I need to extract the 1 and 5 and put it into a new file. Currently I only need to pull the first line, but in the near future I need unlimited. This code works great for one line. I like the idea of just reading the line and then outputting it directly into the file, however when doing two lines, whether I use the \n or not, I only end up with the very last line (ie: 5). The code that works beautifully for one line is:
      #!/usr/bin/perl -w use strict; system ("c:\\Perl\\DataPro\\convert.bat"); open(DPSLOTFILE, "< c:\\Perl\\DataPro\\newreport.txt") or die "Can't o +pen file: $!"; open(OUTFILE, "> c:\\Perl\\DataPro\\output.txt") or die "Can't open fi +le: $!"; while ( <DPSLOTFILE> ) { my $dpdrivloc = "MSL6000 Trinity"; if ( /\Q$dpdrivloc\E:\s*(\d+)/ ) { print OUTFILE "$1"; } } close OUTFILE; close DPSLOTFILE; open (OUTFILE, "< c:\\Perl\\DataPro\\output.txt") or die "Can't open f +ile: $!"; my $slotnumber = <OUTFILE>; print "$slotnumber"; system("c:\\Perl\\DataPro\\omnimm -eject \"MSL6000 Trinity\" $slotnumb +er -location \"blahblahblah\""); close OUTFILE;
      Any comments on how to edit this to write out more than one slot number to the out file is appreciated! Thanks! Ben
Re: $1 into an array
by bageler (Hermit) on Mar 25, 2004 at 19:44 UTC
    try defining slotarray as a hash, which is how you are trying to use it in the assignment. Then you need to access it as a hash, not an array, when you try to print to outfile. If the problem is that $1 is empty then your regexp is not matching, and i suggest tweaking that.
    #open files here my $counter = 0; my %slotarray; while ( <DPSLOTFILE> ) { my $dpdrivloc = "MSL6000 Trinity"; if ( /\Q$dpdrivloc\E:\s*(\d+)/ ) { $slotarray{$counter} = "$1"; #print OUTFILE "$1"; $counter++; } } foreach my $key (keys %slotarray) { print OUTFILE "$key: $slotarray{$key}\n"; } #close files here
Re: $1 into an array
by TomDLux (Vicar) on Mar 26, 2004 at 19:40 UTC

    Three things:

    1. You assign your $1 into a hash but print from an array. As others have said, it's best to assign into an array, using push().
    2. You create a variable, %slotarray, whose scope terminates with the end of the if block. Therefore, the variable is undefined when you go to print. You need to declare the variable at a scope visible to all uses of the variable, in this case, globally. Others have corrected your error, but not explained it.
    3. You don't do actually anything with the saved data.

      Instead of saving $1 into an array, you might as well print it when you find it. But assuming you did plan to do something more sophisticated, such as sorting the elements, you don't need to print the array using a loop ... that's such a C thing to do. Perl is efficient when you deal with sets of data all-at-once, letting Perl do the iterating.

      You might use join():

      print OUTFILE join( "\n", @slotarray ), "\n";

      Alternately, you could locally redefine the $LIST_SEPARATOR, $" :

      { local $" = "\n"; print OUTFILE "@slotarray\n"; }

    --
    TTTATCGGTCGTTATATAGATGTTTGCA