Finding Directories with Find in Bash Using a Exclude List

How do I exclude a directory when using `find`?

Use the -prune primary. For example, if you want to exclude ./misc:

find . -path ./misc -prune -o -name '*.txt' -print

To exclude multiple directories, OR them between parentheses.

find . -type d \( -path ./dir1 -o -path ./dir2 -o -path ./dir3 \) -prune -o -name '*.txt' -print

And, to exclude directories with a specific name at any level, use the -name primary instead of -path.

find . -type d -name node_modules -prune -o -name '*.json' -print

Finding directories with find in bash using a exclude list

Try something like

find /var/www/* \( -path "${Iggy[0]}" $(printf -- '-o -path "*%s" ' "${Iggy[@]:1}") \) -prune -type d

and see what happens.

EDIT: added the leading * to each path as in your example.

And here's a complete solution based on your description.

#!/usr/bin/env bash
basepath="/home/adesso/baldar"
ignore=("/cgi-bin" "/tmp" "/test" "/html" "/icons")

find "${basepath}" -maxdepth 1 -not \( -path "*${ignore[0]}" $(printf -- '-o -path "*%s" ' "${ignore[@]:1}") \) -not -path "${basepath}" -type d

Subdirectories of $basepath excluding those listed in $ignore, presuming at least two in $ignore (fixing that is not hard).

Use find command but exclude files in two directories

Here's how you can specify that with find:

find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*"

Explanation:

  • find . - Start find from current working directory (recursively by default)
  • -type f - Specify to find that you only want files in the results
  • -name "*_peaks.bed" - Look for files with the name ending in _peaks.bed
  • ! -path "./tmp/*" - Exclude all results whose path starts with ./tmp/
  • ! -path "./scripts/*" - Also exclude all results whose path starts with ./scripts/

Testing the Solution:

$ mkdir a b c d e
$ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
$ find . -type f ! -path "./a/*" ! -path "./b/*"

./d/4
./c/3
./e/a
./e/b
./e/5

You were pretty close, the -name option only considers the basename, where as -path considers the entire path =)

find directories but exclude list where directories have a space in name

You could read the exclude file into a Bash array and then craft a find command like this:

mapfile -t exclude < exclude.txt
find ./base_dir \
-mindepth 1 \ # Exclude the current directory
-type d \
-regextype egrep \ # Make sure alternation "|" does not have to be escaped
! -iregex ".*/($(IFS='|'; echo "${exclude[*]}"))" \
-printf '%f\n' # Print just filename without leading directories

resulting in

sub_dir1
sub_dir4

For your example input, the -iregex test expands like this:

$ IFS='|'
$ echo "${exclude[*]}")
sub_dir2|sub dir3

so the regular expression for paths to exclude becomes

.*/(sub_dir2|sub dir3)

The change to IFS is limited to the command substitution.

The limitation to this is if the directories to be excluded contain characters that are special to regexes, you have to escape those, which can get messy. If you wanted to escape, for example, pipes, you could use

echo "${exclude[*]//|/\\|}"

in the command substitution, resulting in

sub_dir2|sub dir3|has\|pipe

where the directory has|pipe with a | in its name has its pipe properly escaped.

Exclude a sub-directory using find

This works:

find /home/feeds/data -type f -not -path "*def/incoming*" -not -path "*456/incoming*"

Explanation:

  • find /home/feeds/data: start finding recursively from specified path
  • -type f: find files only
  • -not -path "*def/incoming*": don't include anything with def/incoming as part of its path
  • -not -path "*456/incoming*": don't include anything with 456/incoming as part of its path

Exclude a directory from find linux

with -prune

find . -name directory_to_exclude -prune -o ...

to exclude many directories

find . \( -name dir1_to_exclude -o -name dir2 ... \) -prune -o ...

Exclude range of directories in find command

You can use wildcards in the pattern for the option -not -path:

find ./ -type f -name "*.bz2" -not -path "./0*/*" -not -path "./1*/*

this will exclude all directories starting with 0 or 1. Or even better:

find ./ -type f -name "*.bz2" -not -path "./[01]*/*"

Exclude list of files from find

I don't think find has an option like this, you could build a command using printf and your exclude list:

find /dir -name "*.gz" $(printf "! -name %s " $(cat skip_files))

Which is the same as doing:

find /dir -name "*.gz" ! -name first_skip ! -name second_skip .... etc

Alternatively you can pipe from find into grep:

find /dir -name "*.gz" | grep -vFf skip_files

Exclude folders when using find

You can use the -path option to exclude certain directory paths in your search:

find / -iregex ".*\.py" ! -path "/your/django/directory"

And you can chain this multiple times if you want to exclude multiple directories:

find / -iregex ".*\.py" ! -path "/your/django/directory" ! -path "/another/dir"

Excluding an array/list of directories in find

If it works, just add ! and -path in front of every element of the array and pass it to find.

 excludedDirList2=('*.' 'node_modules')
findargs=()
for i in "${excludedDirList2[@]}"; do
findargs+=('!' '-path' "$i")
done
find "$dir" -type f -name "hidden.txt" "${findargs[@]}"


Related Topics



Leave a reply



Submit