Page 1 of 1
Root folders only
Posted: 08 Nov 2021 21:48
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\
Re: Root folders only
Posted: 08 Nov 2021 21:52
by highend
A script, foreach loop and getpathcomponent() or gettoken()
or a clever regex to spare the loop^^
Re: Root folders only
Posted: 08 Nov 2021 22:04
by Wanda
I'm sorry, this is greek to me!
But thanks for the quick response!
Re: Root folders only
Posted: 08 Nov 2021 22:35
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?
Re: Root folders only
Posted: 08 Nov 2021 22:55
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.
Re: Root folders only
Posted: 08 Nov 2021 23:01
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
Re: Root folders only
Posted: 08 Nov 2021 23:48
by Wanda
We tested it! Looks perfect! Thanks!

Re: Root folders only
Posted: 08 Nov 2021 23:53
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;
Re: Root folders only
Posted: 10 Nov 2021 15:11
by Wanda
haha, "we" = me and a friend who is helping me on using your code
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!
Re: Root folders only
Posted: 10 Nov 2021 15:27
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.
Re: Root folders only
Posted: 10 Nov 2021 15:37
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...
Re: Root folders only
Posted: 10 Nov 2021 18:46
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.
Re: Root folders only
Posted: 14 Nov 2021 10:46
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...
Re: Root folders only
Posted: 25 Nov 2021 22:48
by Wanda
Ok.
Thanks for the code!