• Directory walk tree

    From Shaun Kulesa@21:1/5 to All on Wed Aug 2 14:03:06 2023
    I have recursive code that will find sub directories in a root directory then find the subdirectories in those directories and so on... I want to store this in a tree structure so I can traverse it in order.

    Is there a tree like structure that I can use to store this? Or is there another method of doing this. I am trying to mimic the subdir output of python's os.walk, it outputs a 2d list of [[directory, [sub_directories], [files]]... ]

    proc get_subdirs {dir} {
    set dirs [list]
    set files [glob -nocomplain -directory $dir -type d *]
    foreach file $files {
    lappend dirs $file
    lappend dirs {*}[get_subdirs $file]
    }
    return $dirs
    }

    proc make_tree {dir previous_dir} {
    set dirs [get_subdirs $dir]

    foreach subdir $dirs {
    make_tree $subdir $dir
    }
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to Shaun Kulesa on Wed Aug 2 17:42:31 2023
    On 8/2/2023 5:03 PM, Shaun Kulesa wrote:
    I have recursive code that will find sub directories in a root directory then find the subdirectories in those directories and so on... I want to store this in a tree structure so I can traverse it in order.

    Is there a tree like structure that I can use to store this? Or is there another method of doing this. I am trying to mimic the subdir output of python's os.walk, it outputs a 2d list of [[directory, [sub_directories], [files]]... ]


    I recall a discussion very similar to this a few months back. I think
    the focus was on how to display it in a tree widget. I remember
    providing some code for it. If you search the recent history of the
    group, you should be able to find something. My news reader doesn't go
    back that far.

    As for a storage model, you can use lists, dict's, struct::tree's, etc.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Shaun Kulesa on Wed Aug 2 21:32:24 2023
    Shaun Kulesa <[email protected]> wrote:
    I have recursive code that will find sub directories in a root
    directory then find the subdirectories in those directories and so
    on... I want to store this in a tree structure so I can traverse it
    in order.

    Is there a tree like structure that I can use to store this? Or is
    there another method of doing this. I am trying to mimic the subdir
    output of python's os.walk, it outputs a 2d list of [[directory, [sub_directories], [files]]... ]

    Does the struct::tree module from Tcllib not meet your needs?:

    https://core.tcl-lang.org/tcllib/doc/tcllib-1-17/embedded/www/tcllib/files/modules/struct/struct_tree.html

    Note also that Tcllib also contains 'fileutil' which contains two
    variants of a 'find' which both will walk directory structures.

    Both give back of list of what was found, so you'd still have to
    marshall their output into struct::tree.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Shaun Kulesa@21:1/5 to All on Thu Aug 3 10:45:41 2023
    Thank you for your suggestions, I tried using struct tree but the documentation is not very helpful.

    How can I rename the root node to ./docs and when I walk the tree what should the -command argument and script look like?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Shaun Kulesa on Thu Aug 3 18:06:50 2023
    Shaun Kulesa <[email protected]> wrote:
    Thank you for your suggestions, I tried using struct tree but the documentation is not very helpful.

    How can I rename the root node to ./docs

    From the man page:

    [1] The root node of the tree can be used in most places
    where a node is asked for. The default name of the
    rootnode is "root", but this can be changed with the
    method re‐ name (see below). Whatever the current name
    for the root node of the tree is, it can be retrieved by
    calling the method rootname.

    Testing the manpage directions:

    $ rlwrap tclsh
    % package require struct::tree
    2.1.2
    % struct::tree tree
    ::tree
    % tree rootname
    root
    % tree rename root ./docs
    ./docs
    % tree rootname
    ./docs
    %


    and when I walk the tree what should the -command argument and script
    look like?

    There is no "-command" option in struct::tree. And there are two walk sub-commands, 'walk' and 'walkproc'. Walk takes a script as argument,
    so not a 'command', so you likely are using 'walkproc' (which takes a
    command prefix). From the docs:

    treeName walkproc node ?-order order? ?-type type? cmdprefix
    This method is like method walk in all essentials, except
    the interface to the user code. This method invokes a
    command prefix with three additional arguments (tree,
    node, and action), instead of evaluating a script and
    passing the node via a loop variable.

    The prefix is invoked with three extra arguments added by the tree
    object: tree, node, action.

    So your command needs, at a minimum, three arguments:

    proc tree-callback {tree node action} { ... }

    And you'd call it by doing:

    tree walkproc root tree-callback

    If you want to pass in additional data, add those arguments before the
    three that the tree object adds:

    proc tree-callback {extra1 extra2 tree node action} { ... }

    And call like so:

    tree walkproc root [list tree-callback $extra_data_1 $extra_data_2]

    Assuming the 'extra' data was in those two variables. Adjust to fit
    your usage.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to Shaun Kulesa on Thu Aug 3 16:19:38 2023
    On 8/2/2023 5:03 PM, Shaun Kulesa wrote:
    I have recursive code that will find sub directories in a root directory then find the subdirectories in those directories and so on... I want to store this in a tree structure so I can traverse it in order.

    Is there a tree like structure that I can use to store this? Or is there another method of doing this. I am trying to mimic the subdir output of python's os.walk, it outputs a 2d list of [[directory, [sub_directories], [files]]... ]


    You could create the tree as you walk the file hierarchy.

    Here is some code that will generate the following output:
    - each entry has 4 items: a flag, the current dir, list of
    sub-directories, and list of file names.
    - Each sub-directory/file mimics the structure above.
    - The flags are "dir" and "file". If the first element is "dir", it is a
    node in the tree. Otherwise, it is a leaf in the tree. You can change
    them to "node" and "leaf" or something else if you want.

    ---------------------
    proc file_processor {dir} {
    set subdirs {}
    foreach dir [glob -nocomplain -types d $dir/*] {
    lappend subdirs [file_processor $dir]
    }

    set files {}
    foreach f [glob -nocomplain -types {b c l p f} $dir/*] {
    lappend files [list "file" $f {} {}]
    }

    return [list "dir" $dir $subdirs $files]
    }
    -------------------------------

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)