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

Dear Monks,

I now have a code that runs but doesn't print what I want

#!/usr/bin/perl; use strict; use warnings; my $fin = "SELECTDAT2"; my $fout = "myfile"; open my $ih, '<', $fin or die "cannot open $fin for reading, $! "; open my $oh, '>', $fout or die "cannot open $fout for writing, $! "; my @records; my @list; while (<$ih>) { my @tokens = split; my $SEC1 = $tokens[3]; my $LAT = $tokens[4]; my $LONG = $tokens[5]; my $DEPTH = $tokens[6]; my $NO = $tokens[10]; my $GAP = $tokens[11]; for $_ (@list) { my ($SEC1, $LAT, $LONG, $DEPTH, $NO, $GAP) = parse_record($_); push @records, [ $SEC1, $LAT, $LONG, $DEPTH, $NO, $GAP ]; } #sort by LONG (index 0=NO, 1=SEC1, 2=LONG, 3=LAT, 4=DEPTH, 5=GAP) my @sorted_recs = sort { $records[$a][2] <=> $records[$b][2] } @record +s; my $nextline = <$ih>; my $y = $tokens[0], my $m = $tokens[1], my $d = $tokens[2], my $h = $t +okens[3]; sub events { my (@list); foreach $nextline (@list) { my @tokens = split; my $SOURCE = $tokens[0]; my $PSEC = $tokens[3]; my $PQ = $tokens[4]; my $SSEC = $tokens[7]; my $SQ = $tokens[8]; last if $nextline eq ""; push (@list, $_); } return @list; } last if eof(); for my $rec (@sorted_recs) { my ($NO, $SEC1, $LONG, $LAT, $DEPTH, $GAP) = @$rec; print $oh "$NO\n", events(@list), "\n", "$SEC1, $LONG, $LAT, $DEPTH, $ +GAP\n"; } } close ($oh); close ($ih);

this is one event from my file SELECTDAT2

82 2 22 1043 54.7 48.020 114.037 17.5 3.2 2.9 13 177 84.3 0.20 +1.6 2.7 C MBMG * 3.1 KALISPELL VALLEY; FELT 3.07 82022210 BUT EP 4432.804ES60.7 LRM IPD4435.40 IS67.2 180. AMM IPD4429.50 ES57.3 133. MSO EPC4415.90 ES32.3 CMT EP 4430.50 IS58.3 LDM IPC4412.20 ES24.3 3 RXF EPC4414.3 CLX IPC4408.70 ES19.7

this is what my code prints out in myfile.

177 events(list) 54.7, 114.037, 48.020, 17.5, 84.3 events(list) , , , , events(list) , , , , events(list) , , , ,

this is what I want printed out

13 'BUT' 4432.80 4 60.7 0 'LRM' 4435.40 0 67.2 0 'AMM' 4429.50 0 57.3 0 'MSO' 4415.90 0 32.3 0 'CMT' 4430.50 0 58.3 0 'LDM' 4412.20 0 24.3 3 'RXF' 4414.3 0 'CLX' 4408.70 0 19.7 0 54.7 114.037 48.020 17.5 177 GO ON TO NEXT EVENT DATA SET

I can't figure why my 'myfile' is not printing out as I want it to with my code.

Replies are listed 'Best First'.
Re: Format file2
by toolic (Bishop) on Jan 25, 2011 at 03:53 UTC
    You should always post the exact error message you are getting. Use "code" tags.

    Your use strict; statement is embedded in a comment line, and is therefore not in effect. Put it on its own line, and you will get compile errors regarding OUT and $OUT.

    Using the following:

    I'd re-write the code as (UNTESTED):
    use strict; use warnings; my $fin = "SELECTDAT2"; my $fout = "myfile"; open my $ih, '<', $fin or die "cannot open $fin for reading, $! "; open my $oh, '>', $fout or die "cannot open $fout for writing, $! "; while (<$ih>) { print $oh "NO", "\n", " 'SOURCE' ", "SEC", "Q", "SEC", "\n", "LONG +", "LAT", "DEPTH", "GAP"; } close $oh; close $ih;
Re: Format file2
by roboticus (Chancellor) on Jan 25, 2011 at 11:26 UTC

    velocitymodel:

    You've already gotten some help on your coding problems. You also asked about putting the data in a different order, so here are a couple hints.

    If you're going to print the records in a different order, you can't print them the instant you see them. Instead, you'll need to store them so you can rearrange them. Something like this can let you store the information:

    my @records; while (<IN>) { # Write a parse_record subroutine to return the variables you want my ($NUM, $SEC, $LONG, $LAT) = parse_record($_); # Stick your variables into an array for later use push @records, [ $NUM, $SEC, $LONG, $LAT ]; }

    Then, you can rearrange the records using some function, like sort:

    # Sort by LONG (index 0=NUM, 1=SEC, 2=LONG, 3=LAT) my @sorted_recs = sort { $$records[$a][2] <=> $$records[$b][2] } @reco +rds;

    Finally, you can print your records once you've sorted them.

    for my $rec (@sorted_recs) { # pull the variables from the current record my ($NUM, $SEC, $LONG, $LAT) = @$rec; print "Num=$NUM, Sec=$SEC, Long=$LONG, Lat=$LAT\n"; }

    To understand what's going on, be sure to read the documentation, such as perldsc, perlsyn, etc.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Format file2
by wfsp (Abbot) on Jan 25, 2011 at 09:03 UTC
    "I wish to pick certain pieces of information from each line..."
    You need to show us what a line looks like.

      My file is on another computer and this file contains over 17000 seismic events recorded from stations. This is what an event would look like in my file.

      The first line is year, month, day, the origin of the quake in hrs, min., sec., the lat., long, depth, magnitude at 3 different places, the no of stations recording the event, the azimuthal gap, dmin, rms, erh, erz, quality, source, other mags, location/ comments. This would look like this in the file;  10 11 01 1127 47.7 44.798 111.367 9.4 .8 2.2 0.0 19 91 0.10 0.4 0.5 b MBMG 0.0 0.0 0.0 7.7 km SSW of Hebgen Dam

      that would be the first line. The other lines contain the actual event data. I want to pick pieces of data from each of these columns of data and sort it into a format for a new file to be run through another program. I don't know how to declare variables when the information is in columns. How do I call the value for the number of stations from that line of code.

        split the line on whitespace and store the results in an array. If the number of stations is the 5th token on the line, access it like this:
        my @tokens = split; my $num_st = $tokens[4];
Re: Format file2
by leslie (Pilgrim) on Jan 25, 2011 at 03:46 UTC

    Dear frd, Read the man page of Open command.

    here I have posted the correct code. Check it.

    use strict; use warnings; $a = "test", $b = "myfile"; open(IN, $a) || die "cannot open for reading, $! "; open(OUT,">$b") || die "cannot open for writing, $! "; + + while (<IN>) { print OUT "NO", "\n", " 'SOURCE' ", "SEC", "Q", "SEC ", "\n", "LON +G", "LAT", "DEPTH", "GAP" } close (IN); close (OUT);