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

I have a file;
ADD TABLE "Benefits" AREA "Employee" DESCRIPTION "The benefits table contains employee benefits." DUMP-NAME "benefits" ADD FIELD "EmpNum" OF "Benefits" AS integer FORMAT "zzzzzzzzz9" INITIAL "0" LABEL "Emp No" POSITION 2 MAX-WIDTH 4 VALEXP "CAN-FIND(employee OF benefits)" VALMSG "Employee must exist." HELP "Please enter the Emp Number" ORDER 10 ADD FIELD "HealthCare" OF "Benefits" AS character FORMAT "x(8)" INITIAL "" LABEL "Health Care" POSITION 3 MAX-WIDTH 16 HELP "Please enter the Health Care field."
In my script when i find a field i want to pick up the line below it to grab the format info;
while (<INFILE1>){ # define variables $FULL_LINE = $_; $TABDISPLAY = 0; $FIELDDISPLAY = 0; $DATEFIELD = 0; $SHORTLINE = substr($FULL_LINE,0,length($FULL_LINE)-2); @LINEARRAY[0..9] = split(/"+/, $SHORTLINE); $FIELDLENGTH = ""; $FIELD = ""; $TYPE = ""; # decide if input line is table name or field name if($LINEARRAY[0]=/ADD TABLE/) { $TABLE="$LINEARRAY[1]"; $TABDISPLAY=1; print OUTFILE3 ("table=" . "$TABLE \n"); } elsif ($LINEARRAY[0]=/ADD FIELD/) { $FIELD=$LINEARRAY[1]; $TYPE=$LINEARRAY[4]; $FIELDDISPLAY=1; #need bit in here to pick up next line to set fieldlength belo +w! $FIELDLENGTH=$LINEARRAY[1]; print OUTFILE3 ("field=" . "$FIELD \n"); print OUTFILE3 ("type=" . "$TYPE \n"); print OUTFILE3 ("length=" . "$FIELDLENGTH \n"); }; #snipped the rest
OUTFILE3 currently looks like;
table=Benefits field=EmpNum type= AS integer length=EmpNum field=HealthCare type= AS character length=HealthCare fieldlength=HealthCare srclength=varcharealthCar field=LifeInsurance type= AS integer length=LifeInsurance
Anybody help?? Thanks

Replies are listed 'Best First'.
Re: How to skip a line?
by ikegami (Patriarch) on Jun 04, 2008 at 09:49 UTC
    You should find paragraph mode ($/ = '';) very useful.
    local $/ = ''; while (<$fh>) { if ( my ($table) = /^ADD TABLE "([^"]+)"/ ) { ... } elsif ( my ($field, $table, $type) = /^ADD FIELD "([^"]+)" OF "([^"]+)" AS (\w+)/ ) { my ($format) = /^ FORMAT "([^"]+)"/m; ... } }

    And note the 'm' modifier on the regexp to change the meaning of '^'.

      Thanks for your help - still not working though! Best to assume ive made a schoolboy error somewhere. Heres my current code. OUTFILE3 is now blank.
      local $/ = ''; # run script while (<$INFILE1>){ # define variables $FULL_LINE = $_; $TABDISPLAY = 0; $FIELDDISPLAY = 0; $DATEFIELD = 0; $SHORTLINE = substr($FULL_LINE,0,length($FULL_LINE)-2); @LINEARRAY[0..9] = split(/"+/, $SHORTLINE); # decide if input line is table name or field name if ( my ($table) = /^ADD TABLE "([^"]+)"/ ) { $TABDISPLAY=1; print OUTFILE3 ("table=" . "$table \n"); } elsif ( my ($field, $table, $type) = /^ADD FIELD "([^"]+)" OF "([^"]+)" AS (\w+)/ ) { my ($format) = /^ FORMAT "([^"]+)"/m; $FIELDDISPLAY=1; my ($format)=$FIELDLENGTH; print OUTFILE3 ("field=" . "$field \n"); print OUTFILE3 ("type=" . "$type \n"); print OUTFILE3 ("length=" . "$FIELDLENGTH \n"); }
        First and most important hint: Call perl with the -w parameter. On Unix you just have a first line "#!/usr/bin/perl -w" which does that automatically, with ActiveState Perl or whatever you are using on windows you might have to use perl /w <scriptname> on the command shell, I don't know how it works there.

        This will tell you that you have defined $table and $format twice (with my). Not a problem and not an error, but it leads to errors later when you want to use the first $format value and get only the second $format.

        It will also tell you that $FIELDLENGTH is undefined. The error message is "Use of uninitialized value in concatenation (.) or string at ./t4.pl line XX" with XX the line in which you print $FIELDLENGTH. So you never put anything into that variable

        Another hint: chomp() can be used to delete CR/LF line endings from a string. Much easier than substr(...) and works on unix too (where there is only one character, CR, as a line ending).