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 )