tags:

views:

88

answers:

5

I have followin code in one legacy script:

while (<FPTR>)  # While still input lines in the file...
{
  if($_ =~ /\x1b&d@
/)
  {
    $aa=$_;
    $aa =~ s/\x1b&d@
/
\x1b&d@/;
    print STDOUT $aa;
  }
...
}

Could you please explain - what doe this code do and how to replace it with correct code? I do not like that there is a line feed in "if" and "=~". Is it possible to change this code?

A: 

That code seems to look for a byte sequence followed by newline and swapping the newkline in front of the pattern. You can use \n for the newline (pr \r\n if the script is in DOS format), the follwoing is equivalent I think:

while (<FPTR>)  # While still input lines in the file...
{
  if($_ =~ m/\x1b&d@\n/)
  {
    $aa=$_;
    $aa =~ s/\x1b&d@\n/\n\x1b&d@/;
    print STDOUT $aa;
  }
...
}
rsp
+1  A: 

You can replace the line feeds with \n. See the section on escape sequences in 'Quote and Quote-like operators' in perldoc perlop.

The $ metacharacter can also be used. From perldoc perlre:

  $ Match the end of the line (or before newline at the end)
eugene y
+3  A: 

Assuming the INPUT_RECORD_SEPARATOR has not been redefined, the newline can probably be replaced by $. Then, you should be able to chomp the copy of the input line to remove the newline. EDIT: Then prepend \n to the output.

while (<FPTR>)  # While still input lines in the file... 
{ 
  if (/\x1b&d@$/) { 
    $aa = $_; 
    chomp $aa;
    print STDOUT "\n" . $aa;
  } 
... 
} 

This would simplify the code by eliminating multiple copies of your regex.

toolic
Problem is that your version does not move the newline to before the pattern like the original script does.
rsp
@rsp: I agree. I completely missed the newline on the RHS of the `s///` delimiter. I have updated my answer.
toolic
A: 

try doing a chomp() first before processing

while (<FPTR>) {
  chomp;
  ....
}
ghostdog74
Sinan Ünür
A: 

This is a tricky one:

/\x1b&d@
/

That's the escape character followed by '&d@' at the end of the line. Therefore, I might actually use:

while (my $line = <FPTR>) {
    if ( $line =~ /x1b&d@$/ ) {
        chomp $line;
        print $line;
    }
}

I do not see why there is a need to make a copy of $_ in $aa, but if that really is necessary, use

if ( (my $copy = $line) =~ /x1b&d@$/ ) {
        chomp $copy;
        print $copy;
    }
}

You only need to specify STDOUT as the filehandle if some other filehandle has been selected as the default.

Sinan Ünür