Page 1 of 1

Compare folders - stripping deeper nested ones

Posted: 01 Dec 2014 01:53
by highend
Hi,

I have two rather equal folder structures. $a is located in D:\Temp and $b in E:\Temp.
I removed the leading paths for this example to make it a bit easier to read / understand.
$a = <<<>>>
a
b
b\c
b\c\d
b\e
b\e\f
b\e\g
c
>>>;

$b = <<<>>>
a
b
c
>>>;
Comparing them and getting only those folders that do exist only in $a is rather easy. It's basically a formatlist with an inverted filter containing $b.

E.g.:
$aStripped = formatlist($a, "f", "<crlf>", "!$b");

This results in:
b\c
b\c\d
b\e
b\e\f
b\e\g
So far that's fine. But I want this list stripped down further by removing all subdirectories that are nested deeper than the new base ("b") + 1.

E.g.
b\c is already unique (it didn't exist in $b)
So:
b\c\d
should be removed

b\e is already unique (it didn't exist in $b)
So:
b\e\f
b\e\g
should be removed

My idea:

Code: Select all

    $aStripped = formatlist($a, "f", "<crlf>", "!$b");
    foreach($line, $aStripped, "<crlf>") {
        $pattern = regexreplace($line, "(\\|\^|\$|\.|\+|\(|\)|\[|\]|\{|\})", "\$1");
        $match   = regexmatches($aStripped, $pattern);
        if (gettoken($match, "count", "|") > 1) { continue; }
        else { $aStripped = regexreplace($aStripped, "^$pattern$"); }
    }
    text formatlist($aStripped, "ens", "<crlf>");
Is there a faster method?

Re: Compare folders - stripping deeper nested ones

Posted: 01 Dec 2014 14:53
by TheQwerty
Not sure if performance wise this is any faster but I find it cleaner:

Code: Select all

  $aStripped = formatlist($a, "f", "<crlf>", "!$b");

  $childFilter = Replace($aStripped, "<crlf>", "\*<crlf>") . "\*";
  $aStripped = FormatList($aStripped, "fends", "<crlf>", "!$childFilter");

  Text $aStripped;
Creates a copy of your match list but appends \* to each item:
b\c\*
b\c\d\*
b\e\*
b\e\f\*
b\e\g\*
Then filters the match list using this to remove the children.

Re: Compare folders - stripping deeper nested ones

Posted: 02 Dec 2014 08:23
by highend
Thanks TheQwerty,

it's indeed much cleaner (and avoids a nasty foreach loop, too) :)

Re: Compare folders - stripping deeper nested ones

Posted: 02 Dec 2014 13:30
by TheQwerty
Looking at this again I overlooked one important factor - if the lists being used as filters contain wildcards, before we add them, then it won't work as expected. Dealing with paths it may be rare but even if they are valid names in Windows they could still have '#' or '[', so both $b and $aStripped need to be escaped.

This should be enough to remedy that:

Code: Select all

$escapedString = RegexReplace($dirtyString, '([?*#[])','[$1]');  //Escape wildcards

And now I shall dream of a day when we have user functions... :whistle:

Re: Compare folders - stripping deeper nested ones

Posted: 02 Dec 2014 18:52
by highend
Thanks!

Is there a reason why you've included "?*"? Both are illegal characters for folders and filenames and (under normal circumstances) you aren't able to create items with any of them in it.

Re: Compare folders - stripping deeper nested ones

Posted: 02 Dec 2014 19:03
by TheQwerty
highend wrote:Is there a reason why you've included "?*"?
Only that I didn't feel there was enough reason to exclude them.

This way if anyone copies the line for use on something other than file names it should still work correctly and escape all of the problematic cases.

Re: Compare folders - stripping deeper nested ones

Posted: 03 Dec 2014 08:34
by highend
This way if anyone copies the line for use on something other than file names it should still work correctly and escape all of the problematic cases.
Yeah, that's true. Thanks again, the folder compare now works absolutely fine :)