Hi.
It is not easy to understand code that has been extracted from a larger source. Here is a shell script that drives a portion of the bash-select-code, but rendered in perl so that you can run it. It calculates the rows and columns as bash would for the select. It does not pretty-print the selections, it just does the calculations. It assumes that you have a file that corresponds to the strings you would use with select. It allows a second parameter, the setting for COLUMNS so that you can see the effects of changing that. Here are a few runs with varying files and widths, the last with some arithmetic and logical internal results displayed. Note that the shell script calls the perl script, so that it is easily posted here, however, you can copy/paste the perl code and run it as desired.
#!/usr/bin/env bash
# @(#) s1 Demonstrate driver for bash select row-col calculations
# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C perl
FILE=${1-data1}
pl " Results, $FILE:"
./p2 $FILE 80
FILE=data2
pl " Results, $FILE:"
./p2 $FILE 80
pl " Results, $FILE 20:"
./p2 $FILE 20
pl " Results, $FILE 80, details:"
./p2 -d $FILE 80
exit 0
producing:
$ ./s1
Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution : Debian 5.0.8 (lenny, workstation)
bash GNU bash 3.2.39
perl 5.10.0
-----
Results, data1:
For data file data1, containing:
fsaaaaa
fsbbbbb
fsccccc
hrddddd
Maximum element length = 7
Final calculation, COLUMNS (width) = 80:
Rows = 4
Cols = 1
-----
Results, data2:
For data file data2, containing:
fsaaaaa
fsbbbbb
fsccccc
hrddddd
None of the above
Maximum element length = 17
Final calculation, COLUMNS (width) = 80:
Rows = 2
Cols = 3
-----
Results, data2 20:
For data file data2, containing:
fsaaaaa
fsbbbbb
fsccccc
hrddddd
None of the above
Maximum element length = 17
Final calculation, COLUMNS (width) = 20:
Rows = 5
Cols = 1
-----
Results, data2 80, details:
debug: value, filename, COLUMNS = data2, 80
debug: value, array a length 5 "fsaaaaa fsbbbbb fsccccc hrddddd None of the above", longest = 17
debug: value initial cols = 4
debug: value before , rows, cols = 2, 4
debug: value after , rows, cols = 2, 3
debug: value adjusted, rows, cols = 2, 3
For data file data2, containing:
fsaaaaa
fsbbbbb
fsccccc
hrddddd
None of the above
Maximum element length = 17
Final calculation, COLUMNS (width) = 80:
Rows = 2
Cols = 3
And here it the perl code, p2:
#!/usr/bin/env perl
# @(#) p2 Demonstrate rows, cols calculations for bash "select".
use warnings;
use strict;
# Short circuit for debug.
# Use with d(), keys: Action, Location, Value.
our ($debug);
$debug = 0;
if ( @ARGV && $ARGV[0] =~ /-de*b*u*g*/ ) {
$debug = 1;
shift;
}
# Read list, calculate longest line.
my ( $filename, $COLUMNS, $f, $longest, $t1, @a, @list );
my ( $list_len, $max_elem_len, $cols, $rows, $string );
$filename = shift || "data1";
$COLUMNS = shift || "80";
d("value, filename, COLUMNS = $filename, $COLUMNS");
open( $f, "<", $filename ) || die "Cannot open file $filename\n";
$longest = 0;
while (<$f>) {
chomp;
$t1 = length($_);
$longest = $t1 > $longest ? $t1 : $longest;
push @a, $_;
}
$list_len = scalar(@a);
d("value, array a length $list_len \"@a\", longest = $longest");
@list = @a;
$max_elem_len = $longest;
$cols = $max_elem_len ? $COLUMNS / $max_elem_len : 1;
$cols = int($cols);
d("value initial cols = $cols");
$cols = 1 if $cols == 0;
$rows = $list_len ? $list_len / $cols + ( $list_len % $cols != 0 ) : 1;
$rows = int($rows);
d("value before , rows, cols = $rows, $cols");
$cols = $list_len ? $list_len / $rows + ( $list_len % $rows != 0 ) : 1;
$cols = int($cols);
d("value after , rows, cols = $rows, $cols");
if ( $rows == 1 ) {
$rows = $cols;
$cols = 1;
}
d("value adjusted, rows, cols = $rows, $cols");
print "\n";
print "For data file $filename, containing:\n";
foreach $string (@list) {
print "$string\n";
}
print " Maximum element length = $max_elem_len\n";
print "\n";
print " Final calculation, COLUMNS (width) = $COLUMNS:\n";
print " Rows = $rows\n";
print " Cols = $cols\n";
exit;
sub d {
# Debug - print strings if debug does not fail.
if ( not $debug ) {
return;
}
elsif ( scalar(@_) == 0 ) {
print "\n";
}
else {
print STDERR join "", "debug: ", @_, "\n";
}
}
Best wishes ... cheers, drl