in reply to column counter and printf question

Perl can count the columns.
use strict; use warnings; while( my $line = <DATA>) { next unless $. > 12; # $. contains current line number next if $line =~ /^$/; # skip blank lines chomp $line; # remove end-of-line character $line =~ s/\s+//; # strip leading whitespace my @columns = split(/\s+/, $line); # split columns on whitespace my $format = "%8.3f" . "%10.3f"x(@columns-3) . "\n"; printf $format, @columns[2..$#columns]; } # my guess at the input data __DATA__ SKIP 1 SKIP 2 SKIP 3 SKIP 4 SKIP 5 SKIP 6 SKIP 7 SKIP 8 SKIP 9 SKIP 10 SKIP 11 SKIP 12 Line_1 0.0 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 Line_2 0.0 0.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 Line_3 0.0 0.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 1.0 Line_4 0.0 0.0 4.0 5.0 6.0 7.0 8.0 9.0 1.0 2.0 Line_5 0.0 0.0 5.0 6.0 7.0 8.0 9.0 1.0 2.0 3.0
Bill

Replies are listed 'Best First'.
Re^2: column counter and printf question
by Anonymous Monk on Oct 28, 2015 at 15:30 UTC
    $line =~ s/\s+//; # strip leading whitespace

    The comment doesn't match the code, it strips the first whitespace it finds. Or perhaps you're missing a ^.

      Oops... thank you. I've corrected that.
Re^2: column counter and printf question
by fasoli (Beadle) on Oct 28, 2015 at 15:53 UTC

    Hi and thanks for the help,

    Can you explain something from this bit

    my $format = "%8.3f" . "%10.3f"x(@columns-3) . "\n";

    Why "@columns-3", what does the "-3" mean? Also, what does "x" mean there? Literally, how many times to repeat the format?

      A printf format is a perl string. In this case, it is constructed using perl's string operators. The dot ('.') is the concatenation operator. The 'x' is the repetition operator (Refer to Multiplicative Operators section of perlop). The specification '10.3f' is repeated @columns-3 times where @columns is the total number of columns. (The three comes from the fact that the first two columns are not printed and the third has it own format specification)
      Bill

        Hi Bill,

        Thanks for the reply and the link, I get it now. Although one more question, should (@columns-3) maybe be ($columns-3)?

        Also, I'm a bit confused over the fact that the following pieces of code produce different output files. Can you take a look at the scripts and let me know where the problem is, as I can't understand it?

        #/bin/perl/ use strict; use warnings; open my $input, '<', './2kc29-out.txt' or die $!; open my $output, '>', 'test_thu1.txt' or die $!; while (my $line = <$input>) { chomp $line; $line =~ s/^\s+//; next if 1 .. $line =~ /\@TYPE xy/; #perlop range operators my @columns = split(/\s+/, $line); my $format = "%8.3f" . "%10.3f"x(@columns-3) . "\n"; printf $output $format, @columns[2..$#columns]; }
        and the second one:
        #/bin/perl/ use strict; use warnings; open my $input, '<', './2kc29-out.txt' or die $!; open my $output, '>', 'test_thu2.txt' or die $!; while (my $line = <$input>) { chomp $line; $line =~ s/^\s+//; next if 1 .. $line =~ /\@TYPE xy/; #perlop range operators my @columns = split /\s+/, $line; my $col1 = shift@columns; # column 1 (ignore) my $col2 = shift@columns; # column 2 (ignore) my $col3 = shift@columns; # column 3 (keep) my $result = printf $output ("%8.3f",$col3); # column 3 format # loop over remaining columns for my $c (@columns) { my $data = printf $output ("%10.3f",$c); $result .= " $data"; # append $result } printf $output "$result\n"; }

        The second script, prints a slightly bigger file (37.51MB over 31,28MB) because in the output it has printed dozens of random "1" numbers right after the last column. Why is this happening?

      Second of your questions in this thread that's easily answered from the docs which came with your distribution.

      See perldoc perldoc et seq.