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

I have a textfile which contains entries one per line in the format of ID|STATUS . example: ... 111|IN 112|IN 113|OUT ... i am trying to make a program that asks over and over for one of the id`s in the textfile, and changes the status to IN when it was OUT and vice versa. Unfortunately i have not been able to make the Code i have come up with work. it would be great if someone can help me make it work...
#!/usr/bin/perl -w $ffdb=("ffdb.dat"); open(FILE, "$ffdb"); @ffdbdata=<FILE>; close FILE; print "Enter ID \n"; $ID = <STDIN>; chomp($ID); if ($ID eq "") { print "Cant be empty!\n"; } open(FILE, ">$ffdb"); foreach $line (@ffdbdata) { $line=~ s/\n//g; @column=split /\|/, "$line"; if ($column[0] eq $ID) { if ($column[1] eq IN) { print FILE "$column[0]|OUT\n"; } else { print FILE "$column[0]|IN\n"; } } else { print FILE "$line\n"; } } close FILE; exit(0);

Replies are listed 'Best First'.
Re: nested if statement wont work
by davidrw (Prior) on Apr 25, 2006 at 15:48 UTC
    how does it not work? does it error? behave badly?

    Be sure to always use strict;

    $column[1] eq IN needs quotes around IN (strict would catch this). But otherwise, looks pretty close
    open(FILE, ">$ffdb"); foreach my $line (@ffdbdata) { chomp $line; # <--- use this instead of s/\n//g my @column=split /\|/, $line; # <-- no need for quotes: "$line" if( $column[0] == $ID ){ $column[1] = $column[1] eq 'IN' ? 'OUT' : 'IN'; # flip the value } print FILE join("|", @column), "\n"; # do one write statement } close FILE;
Re: nested if statement wont work
by Hue-Bond (Priest) on Apr 25, 2006 at 15:58 UTC

    Put a use strict in your code, fix the errors and then you will see:

    Bareword "IN" not allowed while "strict subs" in use at - line 16.

    This is my quick version. Note the differences:

    my $ffdb = "ffdb.dat"; open my $fd, '<', $ffdb or die "open: $!"; chomp (my @ffdbdata = <$fd>); close $fd; print "Enter ID \n"; chomp (my $ID = <STDIN>); print "Cant be empty!\n" unless length $ID; open $fd, '>', $ffdb or die "open: $!"; foreach my $line (@ffdbdata) { my @column=split /\|/, $line; if ($column[0] eq $ID) { print $fd "$column[0]|", $column[1] eq 'IN' ? "OUT\n" : "IN\n"; } else { print $fd "$line\n"; } } close $fd;

    --
    David Serrano

Re: nested if statement wont work
by swampyankee (Parson) on Apr 25, 2006 at 16:25 UTC

    First, a hint: add

    use strict; use warnings; # this has advantages over the -w option
    I believe you'll get a bareword warning on the inner test (if($column[1] eq IN); the bareword IN is probably undef, which will probably not match $column[1]

    So, my second suggestion: get rid of the bareword warning you'll probably get with IN

    emc

    "Being forced to write comments actually improves code, because it is easier to fix a crock than to explain it. "
    —G. Steele
Re: nested if statement wont work
by jwkrahn (Abbot) on Apr 25, 2006 at 21:06 UTC
    You can simplify that by using the Tie::File module:
    #!/usr/bin/perl use warnings; use strict; use Tie::File; my $ffdb = 'ffdb.dat'; tie my @ffdbdata, 'Tie::File', $ffdb or die "Cannot open $ffdb: $!"; print "Enter ID \n"; my $ID = <STDIN>; chomp $ID; if ( $ID eq '' ) { die "Cant be empty!\n"; } foreach ( @ffdbdata ) { s!(?<=^$ID\|)(?:IN|OUT)$!@{[ /IN/ ? 'OUT' : 'IN' ]}! and last; } untie @ffdbdata; exit 0;