in reply to Re^3: Trim Two Characters On Line
in thread Trim Two Characters On Line

Not all please do... This is what I decide to do instead, but what is happening is it is wrapping the line after on the same line.
while(<IN>) { my $line = $_; my $number = () = $line =~ /\,/gi; $line =~ substr( $line, -2, 2, '' ) if ($number > 79); print OUT "$line"; } close OUT; close IN; }

Replies are listed 'Best First'.
Re^5: Trim Two Characters On Line
by AnomalousMonk (Bishop) on Oct 23, 2020 at 21:53 UTC

    No SSCCE or example data accompanies your latest problem statement, so let me reiterate the good advice offered by hippo here. However, please do not post 80-plus field CSV (if that's what you're dealing with) records; 6-12 reasonably-sized fields and a reasonable length threshold should be enough.

    Be that as it may, it's possible to guess at what your problem may be. You do not chomp your records when you read them; there's still a newline at the end of the record. If a record exceeds the limiting number of CSV (?) fields, two characters will be trimmed from the end of the record, and one of them will be the newline. The trimmed, newline-less record is then written to the output file. The next record written to the output file will be effectively concatenated with the previous (newline-less) record, and you have apparent line-wrap.


    Give a man a fish:  <%-{-{-{-<

Re^5: Trim Two Characters On Line
by hippo (Chancellor) on Oct 23, 2020 at 20:38 UTC
Re^5: Trim Two Characters On Line
by soonix (Canon) on Oct 23, 2020 at 22:02 UTC

    Your $line usually has a Newline at the end, which will be one of the characters that you are trimming.

    If you want the newline back, you have to add it back, e.g.
    $line =~ substr( $line, -2, 2, '' ) . "\n"

      Even after fixing the assignment operator (=~ vice =), that doesn't quite work:

      Win8 Strawberry 5.8.9.5 (32) Fri 10/23/2020 18:12:03 C:\@Work\Perl\monks >perl -Mstrict -Mwarnings -MData::Dump=dd my $line = "foo,bar\n"; $line = substr($line, -2, 2, '') . "\n"; dd $line; ^Z "r\n\n"
      A slight variation does:
      >perl -Mstrict -Mwarnings -MData::Dump=dd my $line = "foo,bar\n"; $line = substr($line, 0, -2) . "\n"; dd $line; ^Z "foo,ba\n"

      Update: Another approach is to completely sidestep the newline:

      >perl -Mstrict -Mwarnings -MData::Dump=dd my $line = "foo,bar\n"; substr($line, -3, 2, ''); dd $line; ^Z "foo,b\n"


      Give a man a fish:  <%-{-{-{-<

Re^5: Trim Two Characters On Line
by BillKSmith (Prior) on Oct 24, 2020 at 16:59 UTC
    The following code duplicates your new problem. I am using a memory file to simulate a disk file because I can show exactly what is on it. I am redirecting the output to STDOUT so we can see it. There is only one long line of output because you 'removed' the newline along with the comma.
    use strict; use warnings; use autodie; my $simulation = \do{ 'field 01' . ','x79 . 'field 80,' . "\N{LF}" .'field 01' . ','x79 . 'field 80,' . "\N{LF}" }; *OUT = *STDOUT; my $OFFSET = -2; # second last chracter (the ',') in $line my $LENGTH = 2; # replace 2 charactrers (',' and \n) my $REPLACEMENT = ''; # replace specified characters with nothing open IN, '<', $simulation; while(<IN>) { my $line = $_; my $number = () = $line =~ /\,/gi; substr($line, $OFFSET, $LENGTH) = '' if ($number > 79); print OUT "$line"; } close OUT; close IN;

    In this case, you should only delete one character, the last comma. (Change $LENGTH to 1) Why do you think you should delete two characters? Is my simulation wrong? How? It does assume that you are on a *NIX system. On other systems, perl's IO Layers hide the difference. Your loop should be identical.

    Bill