Use Find Command But Exclude Files in Two Directories

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 =)

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]*/*"

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

exclude multiple directories from find result

Untested: use an array

find_clauses=(
-maxdepth 1
! -path "."
! -path "./tmp"
! -path "./garbage"
-type d
-exec touch {}/dumped ';'
)
find . "${find_clauses[@]}" 2>/dev/null

If you want to put the excluded directories in a list, you can still build the find clauses dynamically:

exclude_dirs=( . ./tmp ./garbage )

find_clauses=( -maxdepth 1 )
for d in "${exclude_dirs[@]}"; do find_clauses+=( ! -path "$d" ); done
find_clauses+=(
-type d
-exec touch {}/dumped ';'
)

find . "${find_clauses[@]}" 2>/dev/null

How to exclude subdirectories of a specific directory from find command?

Just with find:

find /var/www/html -type f -not -path '/var/www/html/folder/*/*'

Original answer:

One hack could be grep -v on the output of find:

find /var/www/html/ -type f | grep -v "/var/www/html/folder/.*/" | wc -l

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"

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

How to skip multiple directories when doing a find

A find expression is composed primarily of tests and actions joined together with operators. It is evaluated in a standard short-circuiting manner -- meaning the evaluation is stopped as soon as the result is known, without the need to evaluate all parts (e.g. true or anything is evaluated to true).

Now note that -prune is an action that always returns true. It can act on the result of any test. Also note that the default operator is -a (and).

So, the simplest pruning example, to print all files except those under some path (e.g. wp-* in your example) looks like:

find . -path './wp-*' -prune -o -print

For files matching the path starting with ./wp-, prune action is executed, meaning the result is true, and the right part of the OR operator can be ignored (i.e. file is not printed). Note here that -path matches relative path, in this case rooted at ., so we have to write ./wp-* instead of wp-*.

To prune two paths, simply extend:

find . -path './wp-*' -prune -o -path ./logs -prune -o -print

Here: if first prune action is not executed (result false), then a chance is given to the second, if that doesn't prune neither (result false), then -print action is executed. In case any -prune gets evaluated, -print doesn't get a chance.

Applying this to your case:

find "$1" -name .bash_history -prune \
-o -path "$1/tmp" -prune \
-o -path "$1/short" -prune \
-o -path "$1/*/_not_used/*" -prune \
-o -path "$1/backups" -prune \
-o -path "$1/temp_logs" -prune \
-o -name "$1/.cpan" -prune \
-o -name "$1/.cpobjcache" -prune \
-o -path "$1/files_to_compare" -prune \
-o -path "$1/logs" -prune \
-o -path "$1/mail" -prune \
-o -path "$1/old" -prune \
-o -path "$1/--*" -prune \
-o -path "$1/wp-*" -prune \
-o -path "$1/*copy*" -prune \
-exec grep $2 -I --color -Hn '$3' '{}' 2>/dev/null \;

To avoid writing $1-dependent paths, you can cd "$1" and use f.e. find . ... -path ./logs ....

Linux Find command- exclude find based on file name

So I'm not sure why, but I ended up fixing this by changing the order of what I'm excluding. Instead of excluding at the very beginning, the following worked (moving the ! -name '.FOO.cs' and ! -name '.fooinfo.cs' to right after the declaration type -f).

I'm assuming this worked because they are files so they must be flagged with type -f. But please comment and correct below if you know why.

find . -type d \( -name Foo-o -name 2Foo -o -name 2_Foo \) -prune -o -type f ! -size 0 ! -name 'FooInfo.cs' ! -name '*.Foo.cs'   \( -name "*.java" -o -name "*.cs" -o -name "*.cpp" -o -name "*.cxx" -o -name "*.cc" -o -name "*.c" -o -name "*.h" -o -name "*.scala" -o -name "*.css" -o -name "*.html" -o -name "*.bat" -o -name "*.js" \) -exec realpath {} \;| xargs grep -L CUSTOMERINFO  | sed -e 's/$/\r/g' >> ../output.txt


Related Topics



Leave a reply



Submit