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

I'm trying to do a replace by character on positions 12 and 13 of a flat file. These positions consistently are populated with "DC" and need to be replaces with two spaces. I don't want to do a global search and replace because there could be DC's elsewhere in the file that should not be replaced. My script is removing the DC's correctly; however, I appear to be losing 10 spaces in the new flat file as a result. This file is going to be used to upload into a database so the character positioning is vital. Any advice on where I'm going wrong? Here's my script:
#!/usr/bin/perl $upload="<upload dir>"; $output="<output dir>"; $inputFile="$upload/inputFile.txt"; $filename="$upload/file.txt.mrk"; $outFile="$output/test.tmp"; open(MYINPUTFILE, "<$filename"); # open for input open(MYOUTPUTFILE, ">>$outFile"); my(@lines) = <MYINPUTFILE>; my($line); foreach $line (@lines) { print $line; substr($line,11,13)=" "; print MYOUTPUTFILE "$line"; } close(MYINPUTFILE); close(MYOUTPUTFILE);

Replies are listed 'Best First'.
Re: Search/Replace Character
by FunkyMonk (Bishop) on Apr 17, 2008 at 15:18 UTC
    The 3rd argument of substr is a length, not another offset! You should be using substr($line,11,2)="  ";


    Unless I state otherwise, my code all runs with strict and warnings
      Aha! Thank you so much. So it's the same logic as it would be with awk, then? Got it. It's working perfectly now.
Re: Search/Replace Character
by elmex (Friar) on Apr 17, 2008 at 15:43 UTC

    As already said, the third paramenter to substr is the length of the addressed substring.

    But for the sake of diversity, here a regex that would work:

    # ... for my $line (@lines) { print $line; $line =~ s/^(.{11})DC/\1 /; print MYOUTPUTFILE $line; } # ...

    And if your script is just for filtering text files you could even reduce the whole thing to a simple command line (if you have a shell, that is):

    elmex@home: ~# cat file.txt.mrk | perl -ne 's/^(.{11})DC/\1 /; pri +nt' >> test.tmp
      If you had warnings in effect, you'd get this message:
      \1 better written as $1
      Thanks for the suggestions. The command line idea will come in really handy. I get a lot of one off text files from my users where a vendor put in a wrong code or put a code in the wrong position and we need to adjust it. This can be a real pain when the file is over 1,000 records or more in some cases.