Image of the glider from the Game of Life by John Conway
Skip to content

Perl, substr, and line feeds

Ok. This may come to most of you as "DUH", but for me and a few helping me, we couldn't figure it out. Consider the following Perl code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
!#/usr/bin/perl -w
open(IN, "oldfile.txt");
open(OUT, ">newfile.txt");
while(<IN>)
{
    $var1=substr($_, 0, 10);
    $var2=substr($_, 10, 5);
    $var3=substr($_, 15, 3);
    substr($_, 0, 3)=$var3;
    substr($_, 3, 10)=$var1;
    substr($_, 13, 5)=$var2;
    print OUT $_;
}
close(IN);
close(OUT);

Fairly straight forward. Nothing fancy here. I've assigned 3 variables some text from the current line, and rearranged their order, then printed out the new order to newfile.txt. If oldfile.txt is 100 characters long on each line, and 500 lines long, then newfile.txt is also 100 characters long on each line and 500 lines long.

However, what if I only want to print the first 18 characters on each line to be in newfile.txt rather than the whole line? Than rather than:

1
print OUT $_;

I would need:

1
print OUT substr($_, 0, 18);

Ah. But do you notice anything wrong with the code above? I didn't, and it took 8 hours of sleep later to figure it out. When printing out the whole line ($_), the line feed as the last character on that line. Thus, newfile.txt will also have the line feed. However, if using substr() in the middle of the line, not including the last character of the line (the line feed), then the line feed doesn't exist, and Perl attempts to write every line on the same line. So, rather, we need to append a line feed at the end:

1
print OUT substr($_, 0, 18) . "\n";

Much better. Something so simple, yet easily overlooked.

Post a Comment

Your email is never published nor shared.

Switch to our mobile site