Hello, is there a module which gives me an output of two columns ( or more ) on STDOUT?
#!/usr/bin/env perl
use warnings;
use strict;
printf "%0.3d\n", $_ for 1 .. 100;
I'd like to have 1-50 in the first column and 51-100 in the second.
Hello, is there a module which gives me an output of two columns ( or more ) on STDOUT?
#!/usr/bin/env perl
use warnings;
use strict;
printf "%0.3d\n", $_ for 1 .. 100;
I'd like to have 1-50 in the first column and 51-100 in the second.
There might be a module for this sort of thing ... or you can roll your own:
use strict;
use warnings;
my $n_cols = shift @ARGV;
my @list = (1..100);
my $part_size = @list / $n_cols;
$part_size = int($part_size + 1) unless $part_size == int($part_size);
my $fmt = '%8s' x $n_cols . "\n";
for my $i (0 .. $part_size - 1){
my @vals = map { defined($list[$_]) ? $list[$_] : '' }
map { $_ * $part_size + $i }
0 .. $n_cols;
printf $fmt, @vals;
}
You can use Perl formatting to do this.
Here is a link with a tutorial on it.
Here is a snippet from that page:
format MYFILE =
Name: @<<<<<<<<<<<<<<<<<<<<<<<<<<<< Salary: @###########.##
$name, $salary
.
Produces the output:
Name: John Smith Salary: 78293.22
The formatting characters have the following formatting characteristics:
> right justified
# right justified (numeric only; can include a decimal point)
< left justified
| center justified
* left justified, fill in all data from value
Edit:
Here is a more direct answer to your question:
#!/usr/bin/perl
use strict;
my @data = (1..100);
my ($v1, $v2);
# Create formats
format ONECOL =
Col1: @###
$v1
.
format TWOCOL =
Col1: @### Col2: @###
$v1, $v2
.
# Set the two column format
$~ = "TWOCOL";
my $i = 0;
my $middle = int(@data/2) + (@data % 2);
for (my $x = $middle; $x < @data; $i++, $x++)
{
$v1 = $data[$i];
$v2 = $data[$x];
write;
}
# Set the format to one column
if ($i < $middle)
{
$~ = "ONECOL";
$v1 = $data[$i];
write;
}
Can you do it this way?
for ($count = 1; $count <=100; $count++) {
printf "%d %d\n", $count, $count+50;
}
This is begging for iterators (not! but it's fun). Note that the revised solution allows you to customize the number of columns as well.
#!/usr/bin/perl
use strict;
use warnings;
use List::AllUtils qw( min );
print_cols('%04d', 1, 100, 11);
sub print_cols {
my ($fmt, $min, $max, $cols) = @_;
my $its = partition($min, $max, $cols);
while ( (my @vals = grep { defined } map {$_->()} @$its)) {
printf join(' ', ($fmt) x @vals) . "\n", @vals;
}
return;
}
sub make_asc_it {
my ($min, $max) = @_;
return sub {
return unless $min <= $max;
return $min ++;
}
}
sub partition {
my ($min, $max, $cols) = @_;
return unless $min <= $max;
my $rows = sprintf '%.0f', ($max - $min) / $cols;
my @its;
for my $col (1 .. $cols) {
push @its, make_asc_it(
min( $min, $max ),
min( $min + $rows - 1, $max )
);
$min += $rows;
}
push @its, make_asc_it($min, $max) if $min <= $max;
return \@its;
}
Output for eleven columns:
0001 0010 0019 0028 0037 0046 0055 0064 0073 0082 0091 0100 0002 0011 0020 0029 0038 0047 0056 0065 0074 0083 0092 0003 0012 0021 0030 0039 0048 0057 0066 0075 0084 0093 0004 0013 0022 0031 0040 0049 0058 0067 0076 0085 0094 0005 0014 0023 0032 0041 0050 0059 0068 0077 0086 0095 0006 0015 0024 0033 0042 0051 0060 0069 0078 0087 0096 0007 0016 0025 0034 0043 0052 0061 0070 0079 0088 0097 0008 0017 0026 0035 0044 0053 0062 0071 0080 0089 0098 0009 0018 0027 0036 0045 0054 0063 0072 0081 0090 0099
use Text::Column qw(format_array_table);
print format_array_table([map [$_, 50+$_], 1..50], [6, 6], [qw(first second)]);
Or, if you're on a UNIX system, pipe through pr(1).
open COLUMN, '|-', qw(pr -T2);
print COLUMN "$_\n" for 1..100;
Have a look at Perl6::Form
use Perl6::Form;
my $col1 = [ 1..50 ];
my $col2 = [ 51..100 ];
print form '{[} {[}', $col1, $col2;
So you can create a helper sub to produce the correct form
which could go something like this:
sub mk_form {
my $rows = shift;
my @form;
# calculate columns needed
use integer;
my $cols = scalar @_ / $rows;
$cols++ if scalar @_ % $rows;
# create Perl6::Form args
push @form, '{[} ' x $cols;
push @form, [ splice @_, 0, $rows ] for 1..$cols;
return @form;
}
Then to produce a columned page at 50 rows:
say form mk_form(50, 1..101);
/I3az/
PS: See SO question What other languages have features and/or libraries similar to Perl’s format? for a bit more about Perl6::Form
.