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

not all of them have the extra commas at the end

Are you trying to read a CSV file? Better use Text::CSV (and its accelerator Text::CSV_XS), it can handle all of the evil edge cases that you didn't even think of.

Would it be okay to send you a message and show you what I am trying to do.

Perlmonks does not work that way. Post detail questions right here in this thread.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Replies are listed 'Best First'.
Re^4: Trim Two Characters On Line
by jalopez453 (Acolyte) on Oct 23, 2020 at 19:20 UTC
    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; }

      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:  <%-{-{-{-<

      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:  <%-{-{-{-<

      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