App-pl

 view release on metacpan or  search on metacpan

pod/examples.pod  view on Meta::CPAN

    >         84: perl-5.30.3/cpan/IO-Compress/t .t
    >         87: perl-5.30.3/cpan/Unicode-Collate/Collate/Locale .pl
    >        103: perl-5.30.3/cpan/Encode/ucm .ucm
    >        117: perl-5.30.3/ext/XS-APItest/t .t
    >        137: perl-5.30.3/dist/Devel-PPPort/parts/base none
    >        137: perl-5.30.3/dist/Devel-PPPort/parts/todo none
    >        138: perl-5.30.3/cpan/Unicode-Collate/t .t
    >        149: perl-5.30.3/pod .pod
    >        206: perl-5.30.3/t/op .t

=item Sum up File-sizes per Suffix

This illustrates a simpler approach: rather than the complicated regexps
above, let Perl split each filename for us.  Find separates output with a dot
and -F splits on that.  The C<\\> is to escape one backslash from the Shell.
No matter how many dots the filename contains, 1st element is the size and
last is the suffix.  Sum it in C<%N(UMBER)>, which gets sorted numerically at
the end:

    find -type f -printf "%s.%f\0" |
        pl -0lF\\. '$NUMBER{@FIELD > 2 ? ".$FIELD[-1]" : "none"} += $FIELD[0]'
    find -type f -printf "%s.%f\0" |
        pl -0lF\\. '$N{@FIELD > 2 ? ".$FIELD[-1]" : "none"} += $FIELD[0]'

    >          0: .configure
    >         16: .perldb
    >         85: .xsh
    >         90: .inf
    >        118: .pmc
    >        138: .plugin
    >   ...
    >    7167163: .c
    >    7638677: .pod
    >    7794749: .h
    >    9742749: .ucm
    >   11124074: .t
    >   11617824: .pm
    >   12259742: .txt

=item Count Files per Date

I<I feel more like I do now than I did a while ago. (-:>

Incredibly, find has no ready-made ISO date, so specify the 3 parts.  If you
don't want days, just leave out C<-%Td>.  Sum up encountered dates in
sort-value-numerically-at-end hash C<%N(UMBER)>:

    find -type f -printf "%TY-%Tm-%Td\n" |
        pl -ln '++$NUMBER{$_}'
    find -type f -printf "%TY-%Tm-%Td\n" |
        pl -ln '++$N{$_}'

    >          1: 2018-07-19
    >          1: 2019-04-10
    >          ...
    >         34: 2020-02-11
    >         93: 2020-02-29
    >       2816: 2018-06-27
    >       3307: 2019-05-11
    >       6024: 2019-10-21
    >      12159: 2019-10-24

=item Count Files per Date with Rollup

I<Learn sign language!  It's very handy. :-)>

Rollup means, additionally to the previous case, sum up dates with the same
prefix.  The trick here is to count both for the actual year, month and day,
as well as replacing once only the day, once also the month with "__", and
once also the year with "____".  This sorts after numbers and gives a sum for
all with the same leading numbers.  Use the sort-by-key-and-stringify-at-end
hash C<%R(ESULT)>:

    find -type f -printf "%TY-%Tm-%Td\n" |
        pl -ln 'do { ++$RESULT{$_} }
            while s/[0-9]+(?=[-_]*$)/"_" x length $&/e'
    find -type f -printf "%TY-%Tm-%Td\n" |
        pl -ln 'do { ++$R{$_} }
            while s/[0-9]+(?=[-_]*$)/"_" x length $&/e'

    >   2018-06-27:  2816
    >   2018-06-__:  2816
    >   2018-07-19:  1
    >   2018-07-__:  1
    >   2018-__-__:  2817
    >   2019-04-10:  1
    >   2019-04-__:  1
    >   ...
    >   2019-11-10:  11
    >   2019-11-25:  6
    >   2019-11-__:  17
    >   2019-12-05:  4
    >   2019-12-__:  4
    >   2019-__-__:  21581
    >   ...
    >   2020-05-14:  33
    >   2020-05-15:  1
    >   2020-05-17:  5
    >   2020-05-29:  4
    >   2020-05-__:  43
    >   2020-__-__:  206
    >   ____-__-__:  24604

=back

=head2 Diff Several Inputs by a Unique Key

I<Always remember you're unique, just like everyone else. :-)>

The function C<k(eydiff)> stores the 2nd arg or chomped C<$_> in C<%K(EYDIFF)>
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

pod/examples.pod  view on Meta::CPAN

    >   	n/a
    >   	H	Hydrogen	1:alkali metal	1
    >   4
    >   	Be	Beryllium	2:alkaline earth metal	9.012
    >   	Pl	Perlium	2:pl basis	5.32.0
    >   	n/a
    >   8
    >   	O	Oxygen	16:O & chalcogen	16
    >   	O	Oxygen	16:O & chalcogen	16
    >   	O	Oxygen	16:O and chalcogen	16
    >   41
    >   	Nb	Niobium	5:no name	92.906
    >   	n/a
    >   	Nb	Columbium	5:no name	93
    >   42
    >   	Ve	Veritasium	6:an element of truth	i
    >   	n/a
    >   	n/a
    >   74
    >   	W	Tungsten	6:transition metal	183.84
    >   	W	Wolfram	6:transition metal	183.8
    >   	n/a
    >   80
    >   	Hg	Mercury	12:no name	200.592
    >   	Hg	Quicksilver	12:no name	200.6
    >   	Hg	Hydrargyrum	12:no name	201
    >   110
    >   	n/a
    >   	Ds	Darmstadtium	10:transition metal	[281]
    >   	Ds	Darmstadtium	10:transition metal	281

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:

    pl -F: 'Keydiff unless /^#/' /etc/passwd passwd*
    pl -n 'keydiff if s/^([^#].*?)://' /etc/passwd passwd*
    pl -F: 'K unless /^#/' /etc/passwd passwd*
    pl -n 'k 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:

    pl -oB 'echo for @ARGV' 'piped {
            keydiff if s@.{29,}% .{16} [\da-f]{8}\K  (.+)@@;
        } "unzip", "-vqq", $_' *.zip
    pl -oB 'e for @A' 'p {
            k if s@.{29,}% .{16} [\da-f]{8}\K  (.+)@@;
        } "unzip", "-vqq", $_' *.zip

    >   perl-5.30.0.zip
    >   perl-5.30.1.zip
    >   perl-5.30.2.zip
    >   perl-5.30.3.zip
    >   AUTHORS
    >   	   48831  Defl:N    22282  54% 2019-05-11 11:50 cc2a1286
    >   	   48864  Defl:N    22297  54% 2019-10-24 23:27 b793bcc5
    >   	   48927  Defl:N    22338  54% 2020-02-29 12:55 8cecd35e
    >   	   48927  Defl:N    22338  54% 2020-02-11 14:31 8cecd35e
    >   Artistic
    >   	    6321  Defl:N     2400  62% 2019-05-11 11:50 fa53ec29
    >   	    6321  Defl:N     2400  62% 2019-10-24 22:17 fa53ec29
    >   	    6321  Defl:N     2400  62% 2019-10-24 22:17 fa53ec29
    >   	    6321  Defl:N     2400  62% 2019-10-21 13:20 fa53ec29
    >   Changes
    >   	    3168  Defl:N     1273  60% 2018-06-27 13:17 66a9af3e
    >   	    3111  Defl:N     1246  60% 2019-10-27 10:52 f826c349
    >   	    3111  Defl:N     1246  60% 2019-10-27 10:52 f826c349
    >   	    3111  Defl:N     1246  60% 2019-10-28 09:05 f826c349
    >   ...

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:

    pl -o 'piped {
            keydiff $2 if s@.{16} ([\da-f]{8})  (.+)@$1@;
        } "unzip", "-vqq", $_' *.zip
    pl -o 'p {
            k $2 if s@.{16} ([\da-f]{8})  (.+)@$1@;
        } "unzip", "-vqq", $_' *.zip

    >   AUTHORS
    >   	   48831  Defl:N    22282  54% cc2a1286
    >   	   48864  Defl:N    22297  54% b793bcc5
    >   	   48927  Defl:N    22338  54% 8cecd35e
    >   	   48927  Defl:N    22338  54% 8cecd35e
    >   Changes
    >   	    3168  Defl:N     1273  60% 66a9af3e
    >   	    3111  Defl:N     1246  60% f826c349
    >   	    3111  Defl:N     1246  60% f826c349
    >   	    3111  Defl:N     1246  60% f826c349
    >   Configure
    >   	  587687  Defl:N   148890  75% 144c0f25
    >   	  587687  Defl:N   148890  75% 144c0f25
    >   	  587825  Defl:N   148954  75% 6761d877
    >   	  587825  Defl:N   148954  75% 6761d877
    >   INSTALL
    >   	  108059  Defl:N    37351  65% 45af5545
    >   	  108085  Defl:N    37371  65% e5f2f22b
    >   	  107649  Defl:N    37211  65% 9db83c1e
    >   	  107649  Defl:N    37211  65% 16726160
    >   ...

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:

    pl -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
    pl -o 'p {
            k $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:

    pl -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
    pl -oB 'e for @A' 'p {
            k $4
                if s!^[^d]\S+ \K(.+?) +(\d+) (.{16}) (.+)!F "%-20s %10d %s", $1, $2, $3!e;
        } "tar", "-tvf", $_' *.tar *.tgz *.txz

    >   perl-5.30.0.txz
    >   perl-5.30.1.txz
    >   perl-5.30.2.txz
    >   perl-5.30.3.txz
    >   ...
    >   cpan/Compress-Raw-Bzip2/bzip2-src/decompress.c
    >   	-r--r--r-- pfeiffer/pfeiffer         20948 2018-06-27 13:17
    >   	-r--r--r-- pfeiffer/pfeiffer         20948 2019-10-24 22:17
    >   	-r--r--r-- pfeiffer/pfeiffer         21287 2020-02-29 12:55
    >   	-r--r--r-- pfeiffer/pfeiffer         21287 2020-02-12 18:41
    >   cpan/Compress-Raw-Bzip2/bzip2-src/huffman.c
    >   	-r--r--r-- pfeiffer/pfeiffer          6991 2018-06-27 13:17
    >   	-r--r--r-- pfeiffer/pfeiffer          6991 2019-10-24 22:17
    >   	-r--r--r-- pfeiffer/pfeiffer          6986 2020-02-29 12:55
    >   	-r--r--r-- pfeiffer/pfeiffer          6986 2020-02-12 18:41
    >   cpan/Compress-Raw-Bzip2/bzip2-src/randtable.c
    >   	-r--r--r-- pfeiffer/pfeiffer          3866 2018-06-27 13:17
    >   	-r--r--r-- pfeiffer/pfeiffer          3866 2019-10-24 22:17
    >   	-r--r--r-- pfeiffer/pfeiffer          3861 2020-02-29 12:55
    >   	-r--r--r-- pfeiffer/pfeiffer          3861 2020-02-12 18:41
    >   cpan/Compress-Raw-Bzip2/fallback/constants.h
    >   	-r--r--r-- pfeiffer/pfeiffer          7238 2018-06-27 13:17
    >   	-r--r--r-- pfeiffer/pfeiffer          7238 2019-10-24 22:17
    >   	-r--r--r-- pfeiffer/pfeiffer          7238 2019-10-24 22:17
    >   	-r--r--r-- pfeiffer/pfeiffer          7238 2019-10-21 13:20
    >   ...

Same without the date:

    pl -o 'piped {
            keydiff $3
                if s!^[^d]\S+ \K(.+?) +(\d+) .{16} (.+)!Form "%-20s %10d", $1, $2!e;
        } "tar", "-tvf", $_' *.tar *.tgz *.txz
    pl -o 'p {
            k $3
                if s!^[^d]\S+ \K(.+?) +(\d+) .{16} (.+)!F "%-20s %10d", $1, $2!e;
        } "tar", "-tvf", $_' *.tar *.tgz *.txz

    >   ...
    >   cpan/Compress-Raw-Bzip2/bzip2-src/decompress.c
    >   	-r--r--r-- pfeiffer/pfeiffer         20948
    >   	-r--r--r-- pfeiffer/pfeiffer         20948
    >   	-r--r--r-- pfeiffer/pfeiffer         21287
    >   	-r--r--r-- pfeiffer/pfeiffer         21287
    >   cpan/Compress-Raw-Bzip2/bzip2-src/huffman.c
    >   	-r--r--r-- pfeiffer/pfeiffer          6991
    >   	-r--r--r-- pfeiffer/pfeiffer          6991
    >   	-r--r--r-- pfeiffer/pfeiffer          6986
    >   	-r--r--r-- pfeiffer/pfeiffer          6986
    >   cpan/Compress-Raw-Bzip2/bzip2-src/randtable.c
    >   	-r--r--r-- pfeiffer/pfeiffer          3866
    >   	-r--r--r-- pfeiffer/pfeiffer          3866
    >   	-r--r--r-- pfeiffer/pfeiffer          3861
    >   	-r--r--r-- pfeiffer/pfeiffer          3861
    >   cpan/Compress-Raw-Bzip2/lib/Compress/Raw/Bzip2.pm
    >   	-r--r--r-- pfeiffer/pfeiffer         10783
    >   	-r--r--r-- pfeiffer/pfeiffer         10783
    >   	-r--r--r-- pfeiffer/pfeiffer         11009
    >   	-r--r--r-- pfeiffer/pfeiffer         11009
    >   ...

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:

    pl -o 'piped {
            keydiff $4
                if s!^[^d]\S+ \K(.+?) +(\d+) (.{16}) [^/]+/(.+)!Form "%-20s %10d %s", $1, $2, $3!e;
        } "tar", "-tvf", $_' *.tar *.tgz *.txz
    pl -o 'p {
            k $4
                if s!^[^d]\S+ \K(.+?) +(\d+) (.{16}) [^/]+/(.+)!F "%-20s %10d %s", $1, $2, $3!e;
        } "tar", "-tvf", $_' *.tar *.tgz *.txz

    >   .dir-locals.el
    >   	-r--r--r-- sawyer/sawyer               208 2018-06-27 13:17
    >   	-r--r--r-- Steve/None                  208 2019-10-24 22:17
    >   	-r--r--r-- Steve/None                  208 2019-10-24 22:17
    >   	-r--r--r-- Steve/None                  208 2019-10-21 13:20
    >   .lgtm.yml
    >   	-r--r--r-- sawyer/sawyer               347 2019-05-11 11:50
    >   	-r--r--r-- Steve/None                  347 2019-10-24 22:17
    >   	-r--r--r-- Steve/None                  347 2019-10-24 22:17
    >   	-r--r--r-- Steve/None                  347 2019-10-21 13:20
    >   .metaconf-exclusions.txt
    >   	-r--r--r-- sawyer/sawyer              1317 2019-05-11 11:50
    >   	-r--r--r-- Steve/None                 1317 2019-10-24 22:17
    >   	-r--r--r-- Steve/None                 1317 2019-10-24 22:17
    >   	-r--r--r-- Steve/None                 1317 2019-10-21 13:20
    >   .travis.yml
    >   	-r--r--r-- sawyer/sawyer              2203 2019-05-11 11:50
    >   	-r--r--r-- Steve/None                 2203 2019-10-24 23:27
    >   	-r--r--r-- Steve/None                 2203 2019-10-24 23:27
    >   	-r--r--r-- Steve/None                 2203 2019-10-21 13:20
    >   AUTHORS
    >   	-r--r--r-- sawyer/sawyer             48831 2019-05-11 11:50
    >   	-r--r--r-- Steve/None                48864 2019-10-24 23:27
    >   	-r--r--r-- Steve/None                48927 2020-02-29 12:55
    >   	-r--r--r-- Steve/None                48927 2020-02-11 14:31
    >   Artistic
    >   	-r--r--r-- sawyer/sawyer              6321 2019-05-11 11:50
    >   	-r--r--r-- Steve/None                 6321 2019-10-24 22:17
    >   	-r--r--r-- Steve/None                 6321 2019-10-24 22:17
    >   	-r--r--r-- Steve/None                 6321 2019-10-21 13:20
    >   Changes
    >   	-r--r--r-- sawyer/sawyer              3168 2018-06-27 13:17
    >   	-r--r--r-- Steve/None                 3111 2019-10-27 10:52
    >   	-r--r--r-- Steve/None                 3111 2019-10-27 10:52
    >   	-r--r--r-- Steve/None                 3111 2019-10-28 09:05
    >   ...

Again without the date and owner/group, which can also vary:

    pl -o 'piped {
           keydiff $2
                if s!^[^d]\S+ \K.+? +(\d+) .{16} [^/]+/(.+)!Form "%10d", $1!e;
        } "tar", "-tvf", $_' *.tar *.tgz *.txz
    pl -o 'p {
           k $2
                if s!^[^d]\S+ \K.+? +(\d+) .{16} [^/]+/(.+)!F "%10d", $1!e;
        } "tar", "-tvf", $_' *.tar *.tgz *.txz

    >   AUTHORS
    >   	-r--r--r--      48831
    >   	-r--r--r--      48864
    >   	-r--r--r--      48927
    >   	-r--r--r--      48927
    >   Changes
    >   	-r--r--r--       3168
    >   	-r--r--r--       3111
    >   	-r--r--r--       3111
    >   	-r--r--r--       3111
    >   Configure
    >   	-r-xr-xr-x     587687
    >   	-r-xr-xr-x     587687
    >   	-r-xr-xr-x     587825
    >   	-r-xr-xr-x     587825
    >   ...

=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:

    pl -O 'piped {
           keydiff if s/^\t(.+\.so.*) => (.*) \(\w+\)/$2/;
        } ldd => $ARGV' exe1 exe2 lib*.so
    pl -O 'p {
           k if s/^\t(.+\.so.*) => (.*) \(\w+\)/$2/;
        } ldd => $A' exe1 exe2 lib*.so

It's even more useful if you use just the basename as a key, because version
numbers may change:

    pl -O 'piped {
           keydiff $2 if s/^\t((.+)\.so.* => .*) \(\w+\)/$1/;
        } ldd => $ARGV' exe1 exe2 lib*.so
    pl -O 'p {
           k $2 if s/^\t((.+)\.so.* => .*) \(\w+\)/$1/;
        } ldd => $A' exe1 exe2 lib*.so

pod/examples.pod  view on Meta::CPAN

            form $f, qw(\\ / +)[$b], map $ARGV->to_base($_), @b;
        last unless $ARGV & ($ARGV - 1);
            if( $b = $ARGV & 1 ) { ++($ARGV += $ARGV >> 1) } else { $ARGV >>= 1 }
        }' 255 511
    pl -OMbignum -B 'f $f = "%s %26s %16s %14s %12s %9s %8s", " ", @b = qw(2 3 4 6 9 10)' '$A += 0; $b = 2;
        e "---" if $I;
        while( 1 ) {
            f $f, qw(\\ / +)[$b], map $A->to_base($_), @b;
        last unless $A & ($A - 1);
            if( $b = $A & 1 ) { ++($A += $A >> 1) } else { $A >>= 1 }
        }' 255 511

    >                              2                3              4            6         9       10
    >   +                   11111111           100110           3333         1103       313      255
    >   /                  101111111           112012          11333         1435       465      383
    >   /                 1000111111           210022          20333         2355       708      575
    >   /                 1101011111          1011222          31133         3555      1158      863
    >   /                10100001111          1202222         110033         5555      1688     1295
    >   /                11110010111          2122222         132113        12555      2588     1943
    >   /               101101100011         10222222         231203        21255      3888     2915
    >   /              1000100010101         12222222        1010111        32125      5888     4373
    >   /              1100110100000         22222222        1212200        50212      8888     6560
    >   \               110011010000         11111111         303100        23104      4444     3280
    >   \                11001101000          2020202         121220        11332      2222     1640
    >   \                 1100110100          1010101          30310         3444      1111      820
    >   \                  110011010           120012          12122         1522       505      410
    >   \                   11001101            21121           3031          541       247      205
    >   /                  100110100           102102          10310         1232       372      308
    >   \                   10011010            12201           2122          414       181      154
    >   \                    1001101             2212           1031          205        85       77
    >   /                    1110100            11022           1310          312       138      116
    >   \                     111010             2011            322          134        64       58
    >   \                      11101             1002            131           45        32       29
    >   /                     101100             1122            230          112        48       44
    >   \                      10110              211            112           34        24       22
    >   \                       1011              102             23           15        12       11
    >   /                      10001              122            101           25        18       17
    >   /                      11010              222            122           42        28       26
    >   \                       1101              111             31           21        14       13
    >   /                      10100              202            110           32        22       20
    >   \                       1010              101             22           14        11       10
    >   \                        101               12             11            5         5        5
    >   /                       1000               22             20           12         8        8
    >   ---
    >   +                  111111111           200221          13333         2211       627      511
    >   /                 1011111111          1001102          23333         3315      1042      767
    >   /                10001111111          1120122         101333         5155      1518     1151
    >   /                11010111111          2100222         122333        11555      2328     1727
    >   /               101000011111         10112222         220133        15555      3488     2591
    >   /               111100101111         12022222         330233        25555      5288     3887
    >   /              1011011000111         21222222        1123013        42555      7888     5831
    >   /             10001000101011        102222222        2020223       104255     12888     8747
    >   /             11001101000001        122222222        3031001       140425     18888    13121
    >   /            100110011100010        222222222       10303202       231042     28888    19682
    >   \             10011001110001        111111111        2121301       113321     14444     9841
    >   /             11100110101010        202020202        3212222       152202     22222    14762
    >   \              1110011010101        101010101        1303111        54101     11111     7381
    >   /             10101101000000        120012002        2231000       123132     16162    11072
    >   \              1010110100000         21121001        1112200        41344      7531     5536
    >   \               101011010000         10210112         223100        20452      3715     2768
    >   \                10101101000          1220021         111220        10224      1807     1384
    >   \                 1010110100           221122          22310         3112       848      692
    >   \                  101011010           110211          11122         1334       424      346
    >   \                   10101101            20102           2231          445       212      173
    >   /                  100000100           100122          10010         1112       318      260
    >   \                   10000010            11211           2002          334       154      130
    >   \                    1000001             2102           1001          145        72       65
    >   /                    1100010            10122           1202          242       118       98
    >   \                     110001             1211            301          121        54       49
    >   /                    1001010             2202           1022          202        82       74
    >   \                     100101             1101            211          101        41       37
    >   /                     111000             2002            320          132        62       56
    >   \                      11100             1001            130           44        31       28
    >   \                       1110              112             32           22        15       14
    >   \                        111               21             13           11         7        7
    >   /                       1011              102             23           15        12       11
    >   /                      10001              122            101           25        18       17
    >   /                      11010              222            122           42        28       26
    >   \                       1101              111             31           21        14       13
    >   /                      10100              202            110           32        22       20
    >   \                       1010              101             22           14        11       10
    >   \                        101               12             11            5         5        5
    >   /                       1000               22             20           12         8        8

This lead to exciting findings L<here|https://perl1liner.sourceforge.io/Collatz/>.

=item Separate Big Numbers with Commas, ...

Loop and print with line-end (B<-opl>) over remaining args in C<$_>.  If
reading from stdin or files, instead of arguments, use only B<-pl>.  After a
decimal dot, insert a comma before each 4th comma-less digit.  Then do the
same backwards from end or decimal dot, also for Perl style with underscores:

    n='1234567 12345678 123456789 1234.5678 3.141 3.14159265358'
    pl -opl '1 while s/[,.]\d{3}\K(?=\d)/,/;
        1 while s/\d\K(?=\d{3}(?:$|[.,]))/,/' $n
    pl -opl '1 while s/[._]\d{3}\K(?=\d)/_/;
        1 while s/\d\K(?=\d{3}(?:$|[._]))/_/' $n

    >   1,234,567
    >   12,345,678
    >   123,456,789
    >   1,234.567,8
    >   3.141
    >   3.141,592,653,58
    >   1_234_567
    >   12_345_678
    >   123_456_789
    >   1_234.567_8
    >   3.141
    >   3.141_592_653_58

The same for languages with a decimal comma, using either a dot or a space as spacer:

    n='1234567 12345678 123456789 1234,5678 3,141 3,141592653589'
    pl -opl '1 while s/[,.]\d{3}\K(?=\d)/./;
        1 while s/\d\K(?=\d{3}(?:$|[.,]))/./' $n
    pl -opl '1 while s/[, ]\d{3}\K(?=\d)/ /;
        1 while s/\d\K(?=\d{3}(?:$|[ ,]))/ /' $n

    >   1.234.567



( run in 1.352 second using v1.01-cache-2.11-cpan-39bf76dae61 )