Filter rule to exclude files in a folder, but not its subfolders

Discuss new features and functions
Posts: 6
Joined: 2 Apr 2021

debiedowner

Quite often, I want to exclude files in a folder, but not its subfolders. E.g. say I want to exclude Folder1 that is in the base directory:
Folder1\
....Folder2\
........File1.ext
........File2.ext
....Folder3\
........File3.ext
........File4
....Folder4\
....File5.ext
....File6.ext
....File7.ext
....File8
The filter rule to exclude Folder1 is \Folder1\, but of course this excludes the subfolders as well. I could not find a way to exclude only the files directly in \Folder1\, trying \Folder1\* doesn't help. I usually don't have files without extensions (i.e. File4 and File8 in this example), so I tried \Folder1\*.*, but this again excludes files in subfolders, as the * wild card character apparently matches the \ path separator character as well. Adding additional include rules doesn't help either, since the exclude rules override them.

The only solution I could find was to add an additional folder pairs for every folder I exclude, and add special include rules for them. E.g. in this example, the base directory pair would have the exclude rule \Folder1\, and then the new folder pair for Folder1 would have the include rule *\ so that it only syncs the subfolders. But I dislike this workaround, because:

1) It is quite cumbersome and inelegant, especially as I need to do this for many, many folders. Ideally I would like to just use a slightly modified exclude rule, which is fundamentally what I want FreeFileSync to do under the hood anyway.

2) Also, I use the "Detect moved files" setting, and I noticed that the additional-folder-pairs workaround causes creation of sync.ffs_db in every folder that I use this workaround for. Again, inelegant (not very important but I would prefer not having superfluous files in multiple deep folders), but also I guess this means that databases are kept separate for the pairs, so moving files would not be detected (I did not test this), when all I wanted in the first place was a single sync pair, just with a slightly different exclude rule.

I think a wild card character that doesn't match path separator characters would solve this issue. E.g. say the : character or maybe ** corresponds to zero or more characters, except the path separator characters \ and /. Then the exclude rule \Folder1\: would match only the files that are direct children of Folder1, and the files in Folder2 and Folder3 would be synced. I am not sure if the exclude rule would cover Folder4, I guess it depends on the implementation, though I wouldn't care either way as I don't tend to have many empty folders. Such a wild card character would allow other more complicated filters that may be desirable to some people, like excluding .txt files from only second level subdirectories (not first level and not third level), and so on.

(If it's actually possible to do this without resorting to the workaround I mentioned, please let me know.)
Posts: 6
Joined: 2 Apr 2021

debiedowner

To put it differently, the footnote in the manual says:
A filter phrase is compared against both file and directory paths. If you want to consider directories only, you can give a hint by appending a path separator.
So it is possible discriminate directories vs. files, what I propose is the ability to discriminate the opposite way, files vs. directories. Indeed, if what I wanted to do was the opposite (exclude files in subfolders but not files that are direct children), it would be easy to achieve with the filter \Folder1\*\, but the reverse does not seem to be possible. That is, since * covers \, it is easy to clarify that I specifically want \, but it is impossible to clarify that I specifically don't want \.

Of course, a way to exclude arbitrary characters from the wild card would also work, but that would take things to the RegEx terrain; a new wild card that just excludes path separator characters would be a simpler solution.
User avatar
Site Admin
Posts: 7212
Joined: 9 Dec 2007

Zenju

The "All subdirectories of the base directories" example on the linked page should do in your case.
Posts: 6
Joined: 2 Apr 2021

debiedowner

I think you misunderstand me, or maybe I am misunderstanding what you are saying. The "All subdirectories of the base directories" example, i.e. the filter phrase "*\" allows me to exclude its subfolders, without excluding files directly in the folder. But what I want to do is the opposite, i.e. exclude files in a folder, without excluding its subfolders.

But like I said, I do use that example you mentioned as a workaround. Sort of like using double negative because positive is not available. i.e. since I can't use something like "\Folder1\**" to exclude files in Folder1 without excluding its subfolders, I just exclude all of Folder1 normally, ("\Folder1\"), and then I add a new folder pair Folder1, using the include (not exclude) rule "*\" that you suggested, to include its subfolders without including files directly in the folder. And I do this for every exclude rule as a workaround; which is quite inconvenient for reasons I mentioned in my post. If there actually was a filter to match just the files, something like "\Folder1\**" or "\Folder1\:" or some other wildcard character, this would be so much simpler, and many other, more advanced filter rules would be possible.
Posts: 6
Joined: 2 Apr 2021

debiedowner

With FreeFileSync version 11.24 adding the feature
Enhanced filter syntax to match files only (append ':')
I hoped that a solution for this was finally added, but it doesn't help.

If I add
\Folder1\*:
to the exclude list, files in the subfolders are still excluded. It does include subfolders, but only as empty folders without the files in them. That is because the "*" character matches the path separator characters too, so "\Folder1\Folder2\File1.ext" gets excluded. So the only thing needed is a wild card character that doesn't match the path separator characters.
User avatar
Posts: 2454
Joined: 22 Aug 2012

Plerry

If you only want to sync files in subfolders of Folder1 and not the files in Folder1 itself, try using an Include Filter rule (as opposed to and Exclude Filter rule), by replacing the standard Include Filter * by \Folder1\*\ or \Folder1\*\* (both should work).
Effectively, you can consider the Include Filter to be the "double negative = positive" you were referring to.

If you want to do the same for a (root) Folder2 of the left and right base location, add a line \Folder2\*\ or \Folder2\*\* to your Include Filter.
etcetera.

If you want to do the same for all (root) folders of the left and right base location, use an Include Filter rule \*\*\ or \*\*\* .
In this latter case, you can still use the Exclude Filter to define root- and/or sub-folders that you do not want to sync.
User avatar
Site Admin
Posts: 7212
Joined: 9 Dec 2007

Zenju

"Multiple folder pairs" is usually the answer to complex filter requirements. First folder pair handles the default. Second folder pair the exception.
Posts: 6
Joined: 2 Apr 2021

debiedowner

@Plerry Folder1 is not a root folder, it is just one of the thousands of deeply nested folders in the drive that I am syncing, that's why this approach doesn't help. So my workaround has been adding additional folder pairs, as @Zenju mentioned, though I described why I dislike that solution and would prefer a solution that works by modifying include and exclude filters.

Perhaps I should describe my use case so that it is easier to visualize. I have 18TB drive that I back up to a 10TB drive, because that is what I have. (I also back up another small drive to the backup drive, so I normally have to folder pairs, say C: -> E: and D: -> E:.) To save space while mirroring to the smaller backup drive, I want to exclude large folders with media that is easily redownloadable. Say D:\some\path\to\large\folder\ is one of such folders that I want to exclude. But D:\some\path\to\large\folder\download\ includes details on how to download them (e.g. a script to redownload the files, if necessary), D:\some\path\to\large\folder\subtitles\ includes subtitles I manually adjusted, D:\some\path\to\large\folder\clips\ includes small clips that I cut for various uses, etc., and I don't want those folders excluded since they are my custom files that are not redownloadable and there is no reason to exclude them since they are tiny anyway.

My problem is that there is no possible exclude filter to exclude files in D:\some\path\to\large\folder\ without excluding files in the subfolders. Once I put \some\path\to\large\folder\ or \some\path\to\large\folder\* in the exclude filter, there is no include filter that manages to include the subfolders, and there is no way to write the exclude filter differently in the first place to not exclude the subfolders.

So I do what @Zenju described: I first exclude \some\path\to\large\folder\ in the D: -> E: folder pair, then I create a new D:\some\path\to\large\folder\ -> E:\some\path\to\large\folder\ pair, then I modify the include filter for this pair from * to *\. This is cumbersome to do compared to just adding an appropriate exclude filter, especially since I constantly run out of space in the backup drive and I need to exclude more media folders. Also it is ugly: semantically all I want to do is back up C: -> E: and D: -> E: with some exclusions inside D:, but instead I have dozens of more pair in addition to the actual pairs. Also this creates superfluous permanent sync.ffs_db in dozens of folders, instead of just at the root of C:, D:, E:.

None of these are major issues, and I am happy that I can make FreeFileSync work the way I want with this additional pairs workaround, but I still read changelogs of every release, hoping that eventually I can get rid of all the superfluous pairs and adding new exclusions will be a simple matter. That's why I got hopeful when I saw the changelog for 11.24 and revisited this subject.