Exclude a sub-directory using find

BashUnix

Bash Problem Overview


I have directory structure like this

data
|___
   |
   abc
    |____incoming
   def
    |____incoming
    |____processed
   123
    |___incoming
   456
    |___incoming
    |___processed

There is an incoming sub-folder in all of the folders inside Data directory. I want to get all files from all the folders and sub-folders except the def/incoming and 456/incoming dirs. I tried out with following command

 find /home/feeds/data -type d \( -name 'def/incoming' -o -name '456/incoming' -o -name arkona \) -prune -o -name '*.*' -print

but it is not working as expected.

Ravi

Bash Solutions


Solution 1 - Bash

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

Solution 2 - Bash

Just for the sake of documentation: You might have to dig deeper as there are many search'n'skip constellations (like I had to). It might turn out that prune is your friend while -not -path won't do what you expect.

So this is a valuable example of 15 find examples that exclude directories:

http://www.theunixschool.com/2012/07/find-command-15-examples-to-exclude.html

To link to the initial question, excluding finally worked for me like this:

find . -regex-type posix-extended -regex ".*def/incoming.*|.*456/incoming.*" -prune -o -print 

Then, if you wish to find one file and still exclude pathes, just add | grep myFile.txt.

It may depend also on your find version. I see:

$ find -version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX

Solution 3 - Bash

-name only matches the filename, not the whole path. You want to use -path instead, for the parts in which you are pruning the directories like def/incoming.

Solution 4 - Bash

find $(INP_PATH} -type f -ls |grep -v "${INP_PATH}/.*/"

Solution 5 - Bash

By following answer for How to exclude a directory in find . command:

find . \( -name ".git" -o -name "node_modules" \) -prune -o -print

Solution 6 - Bash

This is what I did to exclude all the .git directories and passed it to -exec for greping something in the

find . -not -path '*/\.*' -type f -exec grep "pattern" [] \;
  • -not -path '*/\.*' will exclude all the hidden directories
  • -type f will only list type file and then you can pass that to -exec or whatever you want todo

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRaviView Question on Stackoverflow
Solution 1 - Bashsampson-chenView Answer on Stackoverflow
Solution 2 - Bashpeter_the_oakView Answer on Stackoverflow
Solution 3 - BashBrian CampbellView Answer on Stackoverflow
Solution 4 - BashVishal PathakView Answer on Stackoverflow
Solution 5 - BashalperView Answer on Stackoverflow
Solution 6 - BashkedarView Answer on Stackoverflow