CUFP
belg4mit
These are my own perl versions of some C programs at
[http://acme.com/]. lam joins multiple files using the
contents of each as a column in the output. overlay lays two
files on top of each other (as if they were transparencies)
and the second shows through where the first contains
whitespace.
<p>
I imagine overlay can be handy with [http://www.ascii-art.com|ascii-art].
And lam might be useful for making simple brochures...
<p>
Sample lamination:
<pre>
=begin file 1
One fish, two fish.
=end file 1
=begin file 2
Red fish, blue fish.
=end file 2
=begin output
One fish, two fish.Red fish, blue fish.
=end output
</pre>
Sample overlay:
<pre>
=begin file 1
***hello ***
!!!
=end file 1
=begin file 2
...cruel world
I like bananas
=end file 2
=begin output
***hello world***
I like bananas!!!
=end output
</pre>
<readmore>
<b>UPDATE</b>: [danger] made the astute observation
that I was making the nasty assumption of \t == ' 'x8.
Per his suggestion I am now using [Text::Tabs],
and running with -w. There was also a nasty little
bug where I did <code>length($2)</code> instead of
<code>length($two)</code>, guess that's an argument
for picking good variable names ;-). Also, [jeffa]
got a <tt>for</tt> loop.
<p>
<b>UPDATE 2</b>: Bug and robustness fixes from [danger]'s
[id://128998|comment].
<p>
lam source:
<code>
#!/usr/bin/perl -w
use strict;
use Text::Tabs;
use Symbol; #Symbol and
my @data; #array instead of hash so the same file can be in several columns
my $sep ='';
if( $ARGV[0] =~ /^-sep/ ){
(undef, $sep, @ARGV) = @ARGV;
}
die("usage: lam [-sep seperator] file1 file2 [...]\n") unless scalar @ARGV >1;
for(my $i=0; $i < scalar @ARGV; $i++){
open($data[$i]->{FH}=gensym, $ARGV[$i]);
$data[$i]->{w}=0;
while(readline(*{$data[$i]->{FH}})){
my $length = length(expand($_));
$data[$i]->{w} = $length > $data[$i]->{w} ? $length : $data[$i]->{w};
}
$data[$i]->{h} = $.;
seek($data[$i]->{FH}, 0, 0);
}
my $max = (sort {$main::b <=> $main::a} map {$_->{h}} @data)[0];
for(my $j=0; $j<$max; $j++){
for(my $i=0; $i < scalar @ARGV; $i++){
if( $j > $data[$i]->{h} ){
print ' 'x$data[$i]->{w};
}
else{
chomp($_ = readline(*{$data[$i]->{FH}}));
$_ = expand($_);
print $_, ' 'x($data[$i]->{w}-1-length);
}
print $sep unless $i+1 == scalar @ARGV;
}
print "\n";
}
</code>
overlay source:
<code>
#!/usr/bin/perl -w
use strict;
use Symbol;
use Text::Tabs;
die("usage: overlay file1 file2\n") unless scalar @ARGV == 2;
my @data;
for(my $i=0; $i < scalar @ARGV; $i++){
open($data[$i]->{FH}=gensym, $ARGV[$i]) || die("overlay($ARGV[$i]): $!\n");
1 while(readline(*{$data[$i]->{FH}}));
$data[$i]->{LINE} = $.;
seek($data[$i]->{FH}, 0, 0);
}
my $maxline = $data[0]->{LINE} > $data[1]->{LINE} ?
$data[0]->{LINE} : $data[1]->{LINE};
for(my $i=0; $i < $maxline; $i++){
if( $i > $data[0]->{LINE} ){
while(readline(*{$data[1]->{FH}})){
print;
}
last;
}
elsif( $i > $data[1]->{LINE} ){
while(readline(*{$data[0]->{FH}})){
print;
}
last;
}
else{
for my $data (@data){
$data->{str} = readline(*{$data->{FH}});
chomp($data->{str});
$data->{str} = expand($data->{str});
}
my $maxchar = length($data[0]->{str}) > length($data[1]->{str}) ?
length($data[0]->{str}) : length($data[1]->{str});
my @onechars = split(//, $data[0]->{str});
my @twochars = split(//, $data[1]->{str});
my $str;
for(my $j=0; $j<$maxchar; $j++){
if( $j > $#onechars ){
$str .= join('', splice(@twochars, $j));
}
elsif($j > $#twochars){
$str .= join('', splice(@onechars, $j));
}
else{
$str .= $onechars[$j] eq ' ' ? $twochars[$j] : $onechars[$j];
}
}
print $str, "\n";
}
}
</code>
</readmore>
<p>
<tt>
-- <br>
perl -p -e "s/(?:\w);([st])/'\$1/mg"<br>
</tt>