I am wanting to do the following:
- Define an array of globs that specify a base collection of files to include in a process.
- Define an array of globs that specify files to exclude from that process. It doesn't matter to me if this array of globs specifies files not even in the above collection.
- Build an array of files (not globs) that takes all files specified by the include glob array with any file belonging to the exclude glob array removed.
I have been struggling with this. Just to show some explicit examples of progress and what I have attempted, I have tried something like:
# List all files to potentially include in the process
files_to_include=(
'utils/*.txt'
)
# List any files here that should be excluded from the above list
files_to_exclude=(
'*dont-use.txt'
'utils/README.md'
)
# Empty array of files
files=()
for file in ${files_to_exclude[@]}; do
temp=find $files_to_include -type f \( -name '*.txt' -and -not -name $file \)
files+=$temp
done
# I want this to be the total collection of files that I care about
echo ${files[@]}
Obviously, this for loop logic doesn't work, but it's at least something that's got me started, but I'm still struggling with the appropriate way to do this. (I also get weird permission denied messages only when trying to assign the output of find
to temp
that I don't know why they occur.)
I like find
because from what I understand, its performance is going to be much better than grep
. That is an actual concern here because there are a lot of files in my real use case. There are likely several different ways to do this, but I would like to have as little "magic" in my script as possible. So please help to make the script performant but also very understandable.
As far as I can tell, I need a process that expands all the globs in the include array, expands all the globs in the exclude array, and then subtracts the exclude from the include array. This is at a high-level though, and implementing this has been a challenge for me.
Thank you!
find . -type f \( -path "$include1" -o -path "$include2" ... \) ! \( -path "$exclude1" -o -path "$exclude2" \)
, though building the list of args tofind
is a pain (but there's posts on that on the site).grep
would be slow, though. You need to do the comparisons in each case, either infind
or ingrep
, so something likefind . -type f | grep -e ... -e ... | grep -v -e ... -e ...
shouldnt be too bad (barring issues with newlines in filenames and the fact thatgrep
takes regexes instead of globs)