Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use find command but exclude files in two directories

I want to find files that end with _peaks.bed, but exclude files in the tmp and scripts folders.

My command is like this:

 find . -type f \( -name "*_peaks.bed" ! -name "*tmp*" ! -name "*scripts*" \) 

But it didn't work. The files in tmp and script folder will still be displayed.

Does anyone have ideas about this?

like image 495
Hanfei Sun Avatar asked Jan 03 '13 02:01

Hanfei Sun


People also ask

How do I exclude a directory in find?

We can exclude directories by using the help of “path“, “prune“, “o” and “print” switches with find command. The directory “bit” will be excluded from the find search!

How do I exclude a file in Linux?

To do so, create a text file with the name of the files and directories you want to exclude. Then, pass the name of the file to the --exlude-from option.

How do you use prune in find command?

Prune usage:$ find . -prune . The find command works like this: It starts finding files from the path provided in the command which in this case is the current directory(.). From here, it traverses through all the files in the entire tree and prints those files matching the criteria specified.

How do I exclude files from a folder?

(2) Go to the "Settings" tab and Click "Exclude files and locations". Then, click "Browse". (3) Here, at this step, you can use either a file or a folder. Select a file or a folder and click OK.


2 Answers

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

like image 173
sampson-chen Avatar answered Nov 15 '22 17:11

sampson-chen


Here is one way you could do it...

find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)" 
like image 40
alex Avatar answered Nov 15 '22 18:11

alex