URI: 
       initial import from ~/bin - plstree - ps and ls displayed as a tree
  HTML git clone git://bitreich.org/plstree git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/plstree
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
       ---
   DIR commit 35d52859f6fcd9f3d9e411584784f4ccd4b75b87
  HTML Author: Josuah Demangeon <mail@josuah.net>
       Date:   Thu, 19 Apr 2018 04:02:41 +0200
       
       initial import from ~/bin
       
       Diffstat:
         A lstree                              |      98 +++++++++++++++++++++++++++++++
         A pstree                              |     122 +++++++++++++++++++++++++++++++
         A tree                                |      76 +++++++++++++++++++++++++++++++
       
       3 files changed, 296 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/lstree b/lstree
       @@ -0,0 +1,98 @@
       +#!/usr/bin/awk -f
       +
       +# list paths in a tree with some stat infos
       +
       +# Use find(1) walk the entire tree and then call ls -ld with all the
       +# result (ls sort the list itself) with the paths displayed as a tree:
       +#
       +#        drwxr-xr-x   2 josuah  josuah     512 Feb 16 13:19  |- .ssh
       +#        -rw-r--r--   1 josuah  josuah     870 Feb  9 02:24  |  `- config
       +#        drwxr-xr-x   2 josuah  josuah    1536 Feb 18 21:24  |- bin
       +#        -rwxr-xr-x   1 josuah  josuah    1351 Feb 18 22:30  |  |- lt
       +#        -rwxr-xr-x   1 josuah  josuah     565 Feb 17 19:53  |  |- mfilter
       +#        -rwxr-xr-x   1 josuah  josuah    5430 Feb 17 19:51  |  `- xdg-open
       +#        -rwxr-xr-x   1 josuah  josuah     468 Feb 17 19:55  ...
       +
       +BEGIN {
       +        LINE = "|  ";
       +        NODE = "|- ";
       +        TAIL = "`- ";
       +        VOID = "   ";
       +
       +        num = list(entries, ARGC == 1 ? "." : ARGV[1]);
       +        tree(entries, num);
       +
       +        for (l = 1; l <= num; l++) {
       +                for (i = 1; entries[l":"i] != ""; i++)
       +                        printf("%s", entries[l":"i]);
       +                printf("%s\n", entries[l"name"]);
       +        }
       +}
       +
       +# Get a recursive list of all entries into entries[] with entries[i:j]
       +# holding the component j of the path i, and 0 has all the -l details,
       +# then return the number of entries in entries[].
       +#
       +#        [ 1:[ 0:"-rw-r--r-- 1  root root  341 Mar 13 10:50",
       +#              1:"etc" ],
       +#          2:[ 0:"drwxr-xr-x 28 root root 4096 Mar 13 10:50",
       +#              1:"etc",
       +#              2:"sv" ],
       +#          3:[ 0:"drwxr-xr-x  2 root root 4096 Mar 13 10:50",
       +#              1:"etc",
       +#              2:"tor" ] ]
       +#
       +# Only the leaves are present, the intermediates components are LINE or
       +# NODE if just before a leave
       +#
       +#        [ 1:[ 1:LINE, 2:LINE, 3:LINE, 4:LINE, 5:NODE, 6:"filename" ] ]
       +
       +function list(entries, path)
       +{
       +        cmd = "cd '" path "' && exec find ."                                \
       +            " -name '*.git'        -prune -o"                                \
       +            " -name 'CVS'        -prune -o"                                \
       +            " -exec ls -ld {} +";
       +
       +        for (num = 0; cmd | getline; num++) {
       +                sub(" \\.$", "", $0);
       +                sub(" -> .*", "", $0);
       +                infos = $0;
       +                sub(" \\./.*", "", infos);
       +                sub(".* \\./", "./", $0);
       +
       +                entries[num"path"] = $0;
       +                count = split($0, path_v, "/");
       +                for (i = 2; i < count; i++)
       +                        entries[num":"i] = LINE;
       +
       +                entries[num":"count] = NODE;
       +                entries[num":"1] = infos "  ";
       +                entries[num"name"] = path_v[count];
       +        }
       +        close(cmd);
       +
       +        return num - 1;
       +}
       +
       +# Transform entries into a tree by replacing some LINE by VOID when needed.
       +# The tree is walked from the bottom to the top, and column by column
       +# toward the right until an empty column is met.
       +
       +function tree(entries, num)
       +{
       +        for (i = 2; !stop; i++) {
       +                stop = tail = 1;
       +                for (l = num; l > 0; l--) {
       +                        if (entries[l":"i] == LINE && tail) {
       +                                entries[l":"i] = VOID;
       +                                stop = 0;
       +                        } else if (entries[l":"i] == NODE && tail) {
       +                                entries[l":"i] = TAIL;
       +                                tail = stop = 0;
       +                        } else if (!entries[l":"i]) {
       +                                tail = 1;
       +                        }
       +                }
       +        }
       +}
   DIR diff --git a/pstree b/pstree
       @@ -0,0 +1,122 @@
       +#!/usr/bin/awk -f
       +
       +# pstree implementation in awk
       +
       +# Use ps(1) to generate a list of pid, ppid and other properties with
       +# the command name, displayed as a tree built from the pid-ppid pairs:
       +#
       +#        USER     TT        NI   PID STAT COMMAND
       +#        root     ?          0     1 Ss   runit
       +#        josuah   ?          0 22437 S    |- startx
       +#        josuah   ?          0 22451 S    |  `- xinit
       +#        root     tty7       0 22452 Rsl+ |     |- Xorg
       +#        josuah   ?          0 22457 S    |     `- dwm
       +#        josuah   ?          0 24882 S    `- runsvdir
       +#        josuah   ?          0 24884 S       |- runsv
       +#        josuah   ?          0 24887 S       |  |- svlogd
       +#        josuah   ?          0 24890 S       |  `- ratox
       +#        josuah   ?          0 24885 S       `- runsv
       +#        josuah   ?          0 24405 S          |- tor
       +#        josuah   ?          0 24889 S          `- svlogd
       +
       +BEGIN {
       +        LINE = "|  ";
       +        NODE = "|- ";
       +        TAIL = "`- ";
       +        VOID = "   ";
       +
       +        list(entries);
       +        NUM = 1; fill(entries, 1, 0);
       +        tree(entries, NUM);
       +
       +        for (i = 1; i < NUM; i++) {
       +                printf("%s", entries[i":info"]);
       +                for (j = 1; entries[i":"j] != ""; j++)
       +                        printf("%s", entries[i":"j]);
       +                printf("%s\n", entries[i":comm"]);
       +        }
       +}
       +
       +# Build a relational database in <entries> from the output of ps: The
       +# parent pid (ppid) -> pid pairs are used to accumulate a list of child
       +# pid (serialized into a csv: ",234,532,454") later used for building
       +# the tree.
       +#
       +# For each pid, "info" and "comm" are saved as well.
       +
       +function list(entries)
       +{
       +        opt = "-o ppid,user,tty,pid,stat,comm"
       +        cmd = "exec ps -ax " opt " 2>/dev/null";
       +        if (!(cmd | getline)) {
       +                cmd = "exec ps " opt
       +                cmd | getline;
       +        }
       +        sub(" *[^ ]+", "");
       +        print $0;
       +
       +        for (num = 0; cmd | getline; num++) {
       +                ppid = $1; pid = $4;
       +                entries[ppid"cpid"] = entries[ppid"cpid"] "," pid;
       +                sub(" *[^ ]+", "");
       +                sub(" *[^ ]+ + *[^ ]+ + *[^ ]+ + *[^ ]+ +", "&\t");
       +                split($0, info, "\t");
       +                entries[pid"info"] = info[1];
       +                entries[pid"comm"] = info[2];
       +        }
       +        close(cmd);
       +
       +        return num - 1;
       +}
       +
       +# Using the informations from the child pid in entries, build the absolute
       +# path from PID 1 to each pid:
       +#
       +#        [ 1:[ 1:"1" ],
       +#          2:[ 1:"1", 2:"456" ],
       +#          3:[ 1:"1", 2:"456", 3:"1623" ],
       +#          4:[ 1:"1", 2:"456", 3:"1721" ] ]
       +#
       +# With also ":info" and ":comm" for every row.
       +#
       +# Only the leaves are present, the intermediates components are LINE or
       +# NODE if just before a leave
       +#
       +#        [ 1:[ 1:LINE, 2:LINE, 3:LINE, 4:LINE, 5:NODE, 6:"filename" ] ]
       +
       +function fill(entries, pid, lvl)
       +{
       +        for (j = 0; j < lvl; j++)
       +                entries[NUM":"j] = LINE;
       +        entries[NUM":"lvl] = NODE;
       +        entries[NUM":comm"] = entries[pid"comm"];
       +        entries[NUM":info"] = entries[pid"info"];
       +        NUM++;
       +        while (sub("[^,]*,", "", entries[pid"cpid"])) {
       +                cpid = entries[pid"cpid"];
       +                sub(",.*", "", cpid);
       +                fill(entries, cpid, lvl + 1);
       +        }
       +}
       +
       +# Transform entries into a tree by replacing some LINE by VOID when needed.
       +# The tree is walked from the bottom to the top, and column by column
       +# toward the right until an empty column is met.
       +
       +function tree(entries, num)
       +{
       +        for (j = 0; !stop; j++) {
       +                stop = tail = 1;
       +                for (i = num; i > 0; i--) {
       +                        if (entries[i":"j] == LINE && tail) {
       +                                entries[i":"j] = VOID;
       +                                stop = 0;
       +                        } else if (entries[i":"j] == NODE && tail) {
       +                                entries[i":"j] = TAIL;
       +                                tail = stop = 0;
       +                        } else if (!entries[i":"j]) {
       +                                tail = 1;
       +                        }
       +                }
       +        }
       +}
   DIR diff --git a/tree b/tree
       @@ -0,0 +1,76 @@
       +#!/usr/bin/awk -f
       +
       +# convert a list of paths into a tree
       +
       +BEGIN {
       +        LINE = "|  ";
       +        NODE = "|- ";
       +        TAIL = "`- ";
       +        VOID = "   ";
       +
       +        num = list(entries);
       +        tree(entries, num);
       +        display(entries, num);
       +}
       +
       +# Get a recursive list of all entries into entries[] with entries[i:j]
       +# holding the component j of the path i, and 0 has all the -l details,
       +# then return the number of entries in entries[].
       +#
       +#        [ 1:[ 1:"etc" ],
       +#          2:[ 1:"etc", 2:"sv" ],
       +#          3:[ 1:"etc", 2:"tor" ] ]
       +#
       +# Only the leaves are present, the intermediates components are LINE or
       +# NODE if just before a leave
       +#
       +#        [ 1:[ 1:LINE, 2:LINE, 3:LINE, 4:LINE, 5:NODE, 6:"filename" ],
       +#          2:[ 1:LINE, 2:LINE, 3:LINE, 4:NODE, 5:"filename" ] ]
       +
       +function list(entries)
       +{
       +        for (num = 0; getline; num++) {
       +                sub("^/", "", $0);
       +                sub("/$", "", $0);
       +                count = split($0, nodelist, "/");
       +                for (i = 1; i < count; i++)
       +                        entries[num":"i] = LINE;
       +                entries[num":"count] = NODE;
       +                entries[num"name"] = nodelist[count];
       +        }
       +
       +        return num - 1;
       +}
       +
       +# Transform entries into a tree by replacing some LINE by VOID when needed.
       +# The tree is walked from the bottom to the top, and column by column
       +# toward the right until an empty column is met which stops the algorithm.
       +
       +function tree(entries, num)
       +{
       +        for (i = 1; !stop; i++) {
       +                stop = tail = 1;
       +                for (l = num; l > 0; l--) {
       +                        if (entries[l":"i] == LINE && tail) {
       +                                entries[l":"i] = VOID;
       +                                stop = 0;
       +                        } else if (entries[l":"i] == NODE && tail) {
       +                                entries[l":"i] = TAIL;
       +                                tail = stop = 0;
       +                        } else if (!entries[l":"i]) {
       +                                tail = 1;
       +                        }
       +                }
       +        }
       +}
       +
       +# Print all entries line by line.
       +
       +function display(entries, num)
       +{
       +        for (l = 1; l <= num; l++) {
       +                for (i = 1; entries[l":"i] != ""; i++)
       +                        printf("%s", entries[l":"i]);
       +                printf("%s\n", entries[l"name"]);
       +        }
       +}