I chose not to use strict for this one, and it was actually kind of nice for a simple script like this one. Especially the autovivification. Note that the script doesn't work too well if the alignment points you specify don't appear in the same order as you specify them. The script could also be optimized by getting rid of the separate first pass.
#!/usr/bin/perl -w
# align -- align given substrings in standard input lines
use Getopt::Std;
$Getopt::Std::STANDARD_HELP_VERSION = 1;
getopts('a', \%opt);
sub VERSION_MESSAGE {}
sub HELP_MESSAGE {
print <<OPT;
usage: $0 [-s] [string ...]
-a add an extra space before split
You should put the strings in the order that they occur in each line.
Note that only the last string is guaranteed to align.
OPT
}
@splits = @ARGV; # alignment points
@splits = (' #') if not @splits; # default (Perl comment)
while (<STDIN>) {
chomp;
push @lines, $_;
}
for $split (@splits) {
$max = 0;
# Find max column for split string
for (@lines) {
if (/(.+?)(\Q$split\E)(.*)/) {
$max = length $1 if length $1 > $max;
$_ = [$1, "$2$3"];
}
}
# Add one extra space before split
$max++ if $opt{a};
# Add spaces before split
for (@lines) {
$_ = sprintf("%-${max}s%s", $_->[0], $_->[1]) if ref;
}
}
print "$_\n" for @lines;
Here is an example of how to use the script from the UNIX shell:
$ cat example
my $string = 'some value'; # these
my $int = 12; # are
my $float = 1.2; # scalars
$ cat example | ./align = \#
my $string = 'some value'; # these
my $int = 12; # are
my $float = 1.2; # scalars
I personally use it to great effect in vi, so that I can type !}align to align the comments in the next block of code.