App-pltest
view release on metacpan or search on metacpan
pod/examples.pod view on Meta::CPAN
keyed by 1st arg or C<$1> and the arg counter C<$ARGIND> (or C<$I>). Its
sibling C<K(eydiff)> does the same using 1st arg or 0 as an index into
C<@F(IELD)> for the 1st part of the key. At the end only the rows differing
between files are shown. If you write to a terminal or specify B<--color> the
difference gets color-highlighted in per-character detail with
C<Algorithm::Diff>, or in just one red blob without. There are examples for
L<how to alias|canned-commands/Shell Aliases> these as canned commands.
=over
=item Diff Several csv, tsv or passwd Files by 1st Field
This assumes comma-less key fields and no newline in any field. Else you need
a csv-parser package. B<-F> implies B<-a>, which implies B<-n> (even using
older than Perl 5.20, which introduced this idea). B<-F,> splits each line on
commas, and C<K(eydiff)> by default takes the 1st field as your unique key:
pltest -F, Keydiff *.csv
This is similar, but removes the key from the stored value, so it doesn't get
repeated for each file. Note how C<k(eydiff)> by default uses C<$1> as a key
for C<$_>. Additionally, in a B<-B> begin program, show the filenames one per
line:
pltest -nB 'echo for @ARGV' 'keydiff if s/(.+?),//' *.csv
A variant of csv is tsv, with tab as separator. Tab is C<\t>, which must be
escaped from the Shell as C<\\t>, either with or without repeated keys:
pltest -F\\t Keydiff *.tsv
pltest -n 'keydiff if s/(.+?)\t//' *.tsv
The same, with a colon as separator, if you want to compare passwd files from
several hosts. Here we additionally need to ignore commented out lines:
pltest -F: 'Keydiff unless /^#/' /etc/passwd passwd*
pltest -n 'keydiff if s/^([^#].*?)://' /etc/passwd passwd*
=item Diff Several zip Archives by Member Name
I<Growing old you forget to zip up your fly. Later you forget to unzip your fly. 8-)>
This uses the same mechanism as the csv example. Addidionally, through the
C<p(iped)> block, it reads the output of C<unzip -vql> for each archive. That
has an almost fixed format, except with extreme member sizes:
pltest -oB 'echo for @ARGV' 'piped {
keydiff if s@.{29,}% .{16} [\da-f]{8}\K (.+)@@;
} "unzip", "-vqq", $_' *.zip
Java .jar, .ear & .war files (which are aliases for .zip), after a clean build
have many class files with the identical crc, but a different date. This
excludes the date. There are examples for L<how to
combine|canned-commands/Shell Functions> these variants as Shell functions:
pltest -o 'piped {
keydiff $2 if s@.{16} ([\da-f]{8}) (.+)@$1@;
} "unzip", "-vqq", $_' *.zip
Browsers have a bug of not checking for updated css & javascript. A common
workaround is to add a hex number to those file names. In that case use only
the meaningful part of the filename as a key:
pltest -o 'piped {
keydiff $2
if s@.{16} ([\da-f]{8}) (.+?)(?:\.([0-9a-f]{20})(\..[a-z]+))?$@if( $3 ) {
$n = "$2.\$x$4"; "$1 \$x=$3"
} else {
$n = $2; $1
}@e
} "unzip", "-vqq", $_' *.jar
=item Diff Several Tarballs by Member Name
I<Actually I'm very different. But I rarely find time for it. --B< >von HorvE<0xe1>th :-)>
This is like the zip example. Alas, tar gives no checksums, so this is less
reliable. Exclude directories, by taking only lines not starting with a C<d>.
Each time a wider owner/group or file size was seen, columns shift right. So
reformat the columns, to not show this as a difference:
pltest -oB 'echo for @ARGV' 'piped {
keydiff $4
if s!^[^d]\S+ \K(.+?) +(\d+) (.{16}) (.+)!Form "%-20s %10d %s", $1, $2, $3!e;
} "tar", "-tvf", $_' *.tar *.tgz *.txz
Same without the date:
pltest -o 'piped {
keydiff $3
if s!^[^d]\S+ \K(.+?) +(\d+) .{16} (.+)!Form "%-20s %10d", $1, $2!e;
} "tar", "-tvf", $_' *.tar *.tgz *.txz
Tarballs from the internet have a top directory of F<name-version/>, which
across versions would make every member have a different key. So exclude the
1st path element from the key by matching C<[^/]+/> before the last paren
group:
pltest -o 'piped {
keydiff $4
if s!^[^d]\S+ \K(.+?) +(\d+) (.{16}) [^/]+/(.+)!Form "%-20s %10d %s", $1, $2, $3!e;
} "tar", "-tvf", $_' *.tar *.tgz *.txz
Again without the date and owner/group, which can also vary:
pltest -o 'piped {
keydiff $2
if s!^[^d]\S+ \K.+? +(\d+) .{16} [^/]+/(.+)!Form "%10d", $1!e;
} "tar", "-tvf", $_' *.tar *.tgz *.txz
=item Diff ELF Executables by Loaded Dependencies
You get the idea: you can do this for any command that outputs records with a
unique key. This one looks at the required libraries and which file they came
from. For a change, loop with B<-O> and C<$A(RGV)> to avoid the previous
examples' confusion between outer C<$_> which were the cli args, and the inner
one, which were the read lines:
pltest -O 'piped {
keydiff if s/^\t(.+\.so.*) => (.*) \(\w+\)/$2/;
( run in 2.097 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )