Root folders only

Please check the FAQ (https://www.xyplorer.com/faq.php) before posting a question...
Post Reply
Wanda
Posts: 55
Joined: 08 Jan 2011 01:08

Root folders only

Post by Wanda »

Is there a way I can have XYplorer to reduce a list of local addresses, http(s) or ftp to their roots at, user defined value, "x" level of depth only?

Let's say this list is the input...

c:\backup\
c:\backup\sub 1\
c:\backup\sub 2\
c:\backup\sub 2\notes\main\
c:\backup\take\
c:\backup\take\c*
c:\backup\take\d\
c:\backup\transform\
c:\creation\
c:\creation\done

yes, some inputs may have "\" or "/"

Reducing to the minimum common 3rd level folders, I'd like to have

c:\backup\
c:\backup\sub 1\
c:\backup\sub 2\
c:\backup\take\
c:\backup\transform\
c:\creation\
c:\creation\done

Now, reducing to the minimum common 3rd level folders

c:\backup\
c:\creation\

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Root folders only

Post by highend »

A script, foreach loop and getpathcomponent() or gettoken()
or a clever regex to spare the loop^^
One of my scripts helped you out? Please donate via Paypal

Wanda
Posts: 55
Joined: 08 Jan 2011 01:08

Re: Root folders only

Post by Wanda »

I'm sorry, this is greek to me! :titter:

But thanks for the quick response!

autocart
Posts: 1246
Joined: 26 Sep 2013 15:22

Re: Root folders only

Post by autocart »

Wanda wrote: 08 Nov 2021 21:48 ...
Now, reducing to the minimum common 3rd level folders

c:\backup\
c:\creation\
I assume you mean 2nd level at the end?

Wanda
Posts: 55
Joined: 08 Jan 2011 01:08

Re: Root folders only

Post by Wanda »

autocart wrote: 08 Nov 2021 22:35
Wanda wrote: 08 Nov 2021 21:48 ...
Now, reducing to the minimum common 3rd level folders

c:\backup\
c:\creation\
I assume you mean 2nd level at the end?
yes, second level, thanks.

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Root folders only

Post by highend »

If the "input" is in the clipboard...

Code: Select all

    $input = <clp>;

    $lvl = input("Reduce to level", , 1);
    end ($lvl == "" || !regexmatches($lvl, "^[1-9]+$")), "No valid input, aborted!";

    $output = "";
    foreach($item, $input, <crlf>, "e") {
        $fst = regexmatches($item, "^([a-z]:|ftps?:|https?:)(\\|//)?");
        if ($lvl > 1) {
            $item = replace($item, $fst, 5:=1);
            $sep  = (regexmatches($item, "\\")) ? "\" : "/";
            // There is still some string available
            if ($item) {
                $add = gettoken($item, $lvl - 1, $sep, , 1);
                // Take trailing / | \ into account (if it exists)
                $lenAdd = strlen($add);
                $suffix = substr($item, $lenAdd, 1);
                if ($suffix) { $add .= $suffix; }
                // Glue it
                $fst .= $add;
            }
        }
        $output .= $fst . <crlf>;
    }
    // Remove (only following) duplicates, no sorting to remove all!
    $output = formatlist($output, "d", <crlf>);
    text $output;
it would turn this (with level = 3):

Code: Select all

c:\backup\
c:\backup\sub 1\
c:\backup\sub 2\
c:\backup\sub 2\notes\main\
c:\backup\take\
c:\backup\take\c*
c:\backup\take\d\
ftp://www.heise.de/this/is/my/folder
http://www.ibm.com/products
c:\backup\transform\
c:\creation\
c:\creation\done
into this:

Code: Select all

c:\backup\
c:\backup\sub 1\
c:\backup\sub 2\
c:\backup\take\
ftp://www.heise.de/this/
http://www.ibm.com/products
c:\backup\transform\
c:\creation\
c:\creation\done
One of my scripts helped you out? Please donate via Paypal

Wanda
Posts: 55
Joined: 08 Jan 2011 01:08

Re: Root folders only

Post by Wanda »

We tested it! Looks perfect! Thanks! :party:

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Root folders only

Post by highend »

Split personality? oO

This is the regex approach, much cleaner...

Code: Select all

    $input = <clp>;

    $lvl = input("Reduce to level", , 1);
    end ($lvl == "" || !regexmatches($lvl, "^[1-9]+$")), "No valid input, aborted!";

    $range = "{0}";
    if ($lvl > 1) { $range = "{1," . $lvl - 1 . "}"; }
    $output = regexmatches($input, "^([a-z]:\\?|ftps?://|https?://)([^\\/\n]+(?:\\|/)?)" . $range, <crlf>);
    $output = formatlist($output, "d", <crlf>); // Remove (only following) duplicates, not all regardless of position!
    text $output;
One of my scripts helped you out? Please donate via Paypal

Wanda
Posts: 55
Joined: 08 Jan 2011 01:08

Re: Root folders only

Post by Wanda »

haha, "we" = me and a friend who is helping me on using your code :ninja:

Can the output do NOT list files in the output, please?

Second code generates empty lines, can this be fixed?

And a real problem we are having, is there a way the code being able to guess the maximum number of valid levels, picking this as base for the final output? Thanks in advance!

Wanda
Posts: 55
Joined: 08 Jan 2011 01:08

Re: Root folders only

Post by Wanda »

A better usage for the files would be first converting them to their parent folders, can't say it's clear enough for you.

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Root folders only

Post by highend »

Can the output do NOT list files in the output, please?
Why do they exist in the input in the first place if you don't want to process them?
Second code generates empty lines, can this be fixed?
Sure, use "ed", instead of "d" in the formatlist()
is there a way the code being able to guess the maximum number of valid levels, picking this as base for the final output?
What are valid / invalid levels?
And if the max level is chosen, the output would be the same as the input...
One of my scripts helped you out? Please donate via Paypal

Wanda
Posts: 55
Joined: 08 Jan 2011 01:08

Re: Root folders only

Post by Wanda »

Why do they exist in the input in the first place if you don't want to process them?
See the 3rd answer, please.
Sure, use "ed", instead of "d" in the formatlist()
Thanks.
What are valid / invalid levels?
The idea here is having a way to easily distinguish which folders are being in use in recent times, clicking the "branch view" button, sorting by modified and grabbing file paths from there.

The constant usage of this is demanding a smarter solution, thus the request for a way the code deciding for itself the deepest valid folders which in turn would preserve higher levels.

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Root folders only

Post by highend »

Code: Select all

    $input = <clp>;
    end ($input == ""), "Nothing in clipboard, aborted!";

    $lvl = input("Reduce to level", , getMaxLevel($input));
    end ($lvl == "" || !regexmatches($lvl, "^[1-9]+$")), "No valid input, aborted!";

    $output = "";
    foreach($item, $input, <crlf>, "e") {
        if ($item == "") { continue; }
        $fst = regexmatches($item, "^([a-z]:|ftps?:|https?:)(\\|//)?");
        if ($lvl > 1) {
            $item = replace($item, $fst, 5:=1);
            $sep  = (regexmatches($item, "\\")) ? "\" : "/";
            // There is still some string available
            if ($item) {
                $add = gettoken($item, $lvl - 1, $sep, , 1);
                // Take trailing / | \ into account (if it exists)
                $lenAdd = strlen($add);
                $suffix = substr($item, $lenAdd, 1);
                if ($suffix) { $add .= $suffix; }
                // Glue it
                $fst .= $add;
            }
        }
        $output .= $fst . <crlf>;
    }
    // Remove (only following) duplicates, no sorting to remove all!
    $output = formatlist($output, "d", <crlf>);

    text $output;


function getMaxLevel($input) {
    $maxLvl = 0;

    foreach($item, $input, <crlf>, "e") {
        if ($item == "") { continue; }
        // if (regexmatches($item, "heise")) { step; }
        $sep  = (regexmatches($item, "\\")) ? "\" : "/";
        $root = regexmatches($item, "^([a-z]:|ftps?:|https?:)(\\|//)?");
        $rest = replace($item, $root, 5:=1);

        $lvl = 0;
        if ($rest) {
            // If it looks like a file => convert to folder (with trailing $sep)
            if (regexmatches($rest, "(\\|/)[^.]+?\.[^.]+?$")) {
                $cnt  = gettoken($rest, "count", $sep);
                $rest = gettoken($rest, $cnt - 1, $sep, , 1);
            }
            $rest = trim($rest, $sep, "R");
            $lvl  = gettoken($rest, "count", $sep);
        }
        $lvl = 1 + (($lvl) ? $lvl : 0);

        if ($lvl > $maxLvl) { $maxLvl = $lvl; }
    }
    return $maxLvl;
}
If there is anything else, you need to do that yourself...
One of my scripts helped you out? Please donate via Paypal

Wanda
Posts: 55
Joined: 08 Jan 2011 01:08

Re: Root folders only

Post by Wanda »

Ok.
Thanks for the code!

Post Reply