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

Hello again,
You all did a wonderful job helping with my last script I had to come back and try again :)

I have been working on a script this time that will take some input from the user. (lets say the inputs name is LOT, W, tester). From this information it will then parse out a file that is already automatically created by a machine and get another bit of information from one of the lines.

What is happeneing here is that the W info they give us is also known by the name TS by the machine. to find TS the techs have to go looking through a file to find it and asked I make it easier. Once the TS is found, I can then tell the machine to look for a certain file name in a certain directory and have that file unzipped for them.

Below is the code I have so far, though I dont have it all there just the part i want to work really. the last part of it that unzipps will be easy...it is the parsing that i have a problem with.
#!/usr/local/bin/perl use warnings; use strict; my @results; print "Please enter the lot number: "; my $l = <STDIN>; print "Your lot number is $l"; print "Please enter the wafer number: "; my $w=<STDIN>; print "Your wafer number is $w"; print "Please enter the tester number: "; my $t = <STDIN>; print "Your tester number is $t"; my $sdtfile = "C:\\bzip\\sdt.log"; if (open (MAPFILE, "< $sdtfile")) { my @lines = <MAPFILE>; print "$l\n$w\n$t\n"; foreach $line (@lines) { my $cnt++; my @tokens = split(/,/, $line); my $date = lc($tokens[0]); my $time = lc($tokens[1]); my $lot = lc($tokens[2]); #print "$lot\n"; my $waf = lc($tokens[3]); #print "$waf\n"; my $ts = lc($tokens[4]); #print "$ts\n"; my $sstep = lc($tokens[5]); my $machine = lc($tokens[6]); #my $prog = lc($tokens[7]); my $product = lc($tokens[8]); my $plnfile = lc($tokens[9]); my $striping = lc($tokens[10]); if ($w ne "" ) { if (($l eq $lot) && ($w eq $waf)) { #print "Match found on machine $t\n"; #print "Timestamp is $ts\n"; #print "uncompressing any bz2 files\n"; #print "Your Datalog file is dl$ts.$t.bz2"; #push(@results, "$date,$time,$lot,$waf,$ts,$sstep,$machine +,$product,$plnfile,$striping"); #system("C:\\bzip\\bunzip2.exe C:\\bzip\\dl$ts.$t.bz2"); } } } }


here is a sample $sdtfile:
10/11/05,17:05:41,LOT1,W1,ts01,Sstep1,tester1,prog1,prod1,plan1, 10/11/05,19:24:01,LOT1,W2,ts02,Sstep2,tester1,prog2,prod2,plan2,Stripi +ng1 10/11/05,22:46:23,LOT2,W3,ts03,Sstep3,tester3,prog3,prod3,plan3, 10/12/05,01:09:40,LOT2,W4,ts04,Sstep4,tester4,prog4,prod4,plan4,


Lets say the LOT you are looking for is LOT2, the W you are looking for is W3 and the tester you are looking for is tester3.

please let me know if there is anymore informatio needed.

Sorry, I tried the readmore tags and it does nto seem to work. I hope this is not too long of a post.

Replies are listed 'Best First'.
Re: parsing data from file
by graff (Chancellor) on Oct 16, 2005 at 03:42 UTC
    I think you need to use "chomp" on the variables that are input from the user:
    # ... prompt and read user input ... then: chomp $l, $t, $w;
    If you don't do that, the final 'newline' character(s) that were part of the user's input are retained at the end of each string, and these will never match the file data you are comparing it to. (Notice that the last element of data read from the file, "$striping", will also contain the final "newline" characters that are found at the end of each line in the file, because you are not using chomp on the file input either.

    Also, maybe you need to be clear about whether the user is supposed to provide just numbers for those three input values, or whether they are supposed to be alphanumeric strings like "LOT1", "W2" and "tester3". As you've posted it, if they just put in numbers (as instructed), you are not adding the alphabetic parts that will allow them to match the fields in the file data.

    Another alternative (which I would personally consider to be a better idea), is to have the user provide his three input values on the command line, following the name of the script. The script then fetches the values from @ARGV -- and note that values in @ARGV don't have newline characters at the end, so you don't need to chomp them:

    my $Usage = "Usage: $0 LOT# W# tester#\n"; die $Usage unless ( @ARGV==3 and join(" ",@ARGV) =~ /LOT\d+ W\d+ teste +r\d+/ ); my ( $l, $w, $t ) = @ARGV; print "Command line args were:\n $l\n $w\n $t\n"; my $sdtfile = "C:\\bzip\\sdt.log"; if (open (MAPFILE, "< $sdtfile")) { my @lines = <MAPFILE>; chomp @lines; my @fields = qw/time lot waf ts sstep machine product plnfile stri +ping/; my %row; foreach $line (@lines) { @row{@fields} = split /,/, $line; if ($l eq $row{lot} && $w eq $row{waf}) { # do something... } } }
    BTW, it looks to me like the readmore tags are working. When I view the post directly, I see your code with a shaded background, whereas when it appears in the "Seekers of Perl Wisdom" index page (among other posts in this section) the code is hidden.
Re: parsing data from file
by punkish (Priest) on Oct 16, 2005 at 02:06 UTC
    It is not clear at all what problem you are facing... your code could be simplified, but it is mostly ok. Are you getting any errors? What is it that you want help with? In the meantime, here are a few code-cleanup suggestions

    # chop the inputs to remove the trailing \n my $l = <STDIN>; chop($l); .. and so on.. # use while to loop over the lines in the file open MAPFILE "$sdtfile" or die; while (<MAPFILE>) { my ($date, $time, $lot, $waf, $ts, $sstep, $machine, $prog, $product +, $plnfile, $striping) = split(/,/, $_); if (..) { # rest of the program } }
    --

    when small people start casting long shadows, it is time to go to bed

      ack! why use chop when you can use the safer chomp? And how come neither was used inside the while (<MAPFILE>)? Finally, why did you remove the call to lc?

      # chomp the inputs to remove the trailing \n chomp(my $l = <STDIN>); . . . # 3-arg open safer. # No use putting quotes around $sdtfile. open(MAPFILE, '<', $sdtfile) or die("Unable to open map file: $!\n"); # No need to load whole file in memory. # Use while instead of foreach. while (<MAPFILE>) { my ( $date, $time, $lot, $waf, $ts, $sstep, $machine, $prog, $product, $plnfile, $striping, ) = map lc, split(/,/, $_); if (...) { . . . } }
Re: parsing data from file
by dorko (Prior) on Oct 16, 2005 at 03:39 UTC
    In addition to the comments from punkish and ikegami, I believe my $cnt++; doesn't do what you think it does.

    Cheers,

    Brent

    -- Yeah, I'm a Delt.