I am trying to run find
to exclude a list of directories that I have in a file. This file is used by a different command as well so I am stuck with the format of the file, which is each line contains the directory name "as is" followed by a slash, e.g.
My Files/
I tried various things such as xargs which I could not get to work but finally settled on pre-processing the blacklist to produce the arguments to find like this:
find . -type f $(cat .blacklist.txt | while read -r line; do printf "! -path './%s*' -prune " "$line"; done)
However, whenever I encounter a directory name in the blacklist which has spaces in it, I get the error:
find: paths must precede expression: `<Last Part Of Name>/*''
I used set -x
to try to figure out what is going on, and it appears that the separate parts of the directory name are being individually quoted. For instance, suppose I have a directory name in the list called "My Files". I see this output from set -x
for this particular line of the file:
++ printf '! -path '\''./%s*'\'' -prune ' 'My Files/'
So far so good I think. But when I see the output of this in the final assembled command, it looks like this:
'!' -path ''\''./My' 'Files/*'\''' -prune
The problem is obvious: it's turning my directory name which I worked so hard to keep in one piece, into two pieces! But I can't see why it would be doing this. I have tried a few variations, for instance instead of:
printf "! -path './%s*' -prune " "$line"
I think that somehow I need to make sure that the resulting output of the path is quoted when it comes out of the printf, but I have tried all of these and none of them worked:
printf "! -path \"./%s*\" -prune " "$line"
printf "! -path "'./$line*'" -prune "
printf "! -path '"./$line*"' -prune "
But none of these stopped the individual words in the directory name from being split apart.
I also tried this:
printf "! -path ./%s* -prune " "$line"
This avoids splitting the directory name, but as it's no longer quoted it is getting expanded into all the sub-directories under that path which is wrong and also breaks the command as now there are multiple sub-directories where only one directory is expected.
It also does not seem to matter if I use %s
followed by the argument as a separate parameter to printf
, or if I substitute %s
with $line
directly.
set -x
I'm still seeing the parts of the directory name get split up.