Làm thế nào để loại trừ một thư mục trong tìm kiếm. chỉ huy

1492
helion3 2010-11-18 12:57.

Tôi đang cố chạy một findlệnh cho tất cả các tệp JavaScript, nhưng làm cách nào để loại trừ một thư mục cụ thể?

Đây là findmã chúng tôi đang sử dụng.

for file in $(find . -name '*.js') do java -jar config/yuicompressor-2.4.2.jar --type js $file -o $file
done

30 answers

1272
f10bit 2010-11-18 13:00.

Sử dụng công -prunetắc. Ví dụ: nếu bạn muốn loại trừ miscthư mục, chỉ cần thêm một -path ./misc -prune -ovào lệnh find của bạn:

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

Đây là một ví dụ với nhiều thư mục:

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

Ở đây chúng tôi loại trừ ./dir1 , ./dir2./dir3 trong thư mục hiện tại, vì trong findbiểu thức, nó là một hành động hoạt động trên các tiêu chí -path dir1 -o -path dir2 -o -path dir3(nếu dir1 hoặc dir2 hoặc dir3 ), ANDed với type -d.

Để loại trừ tên thư mục ở bất kỳ cấp độ nào, hãy sử dụng -name:

find . -type d \( -name node_modules -o -name dir2 -o -path name \) -prune -false -o -name '*.json'
2046
GetFree 2013-04-01 15:26.

Nếu -prunekhông hiệu quả với bạn, điều này sẽ:

find -name "*.js" -not -path "./directory/*"

Cảnh báo: yêu cầu duyệt qua tất cả các thư mục không mong muốn.

487
Daniel C. Sobral 2013-05-17 09:01.

Tôi thấy điều sau đây dễ lập luận hơn các giải pháp được đề xuất khác:

find build -not \( -path build/external -prune \) -name \*.js
# you can also exclude multiple paths
find build -not \( -path build/external -prune \) -not \( -path build/blog -prune \) -name \*.js

Lưu ý quan trọng: các đường dẫn bạn nhập sau -pathphải khớp chính xác với những gì findsẽ in mà không có loại trừ. Nếu câu này confuses bạn chỉ cần đảm bảo sử dụng đường dẫn đầy đủ thông qua ra toàn bộ lệnh như thế này: . Xem ghi chú [1] nếu bạn muốn hiểu rõ hơn.find /full/path/ -not \( -path /full/path/exclude/this -prune \) ...

Bên trong \(\)là một biểu thức sẽ khớp chính xác build/external (xem lưu ý quan trọng ở trên), và khi thành công, hãy tránh đi qua bất kỳ điều gì bên dưới . Sau đó, biểu thức này được nhóm lại thành một biểu thức duy nhất với dấu ngoặc đơn có dấu ngoặc đơn và có tiền tố -notsẽ findbỏ qua bất kỳ biểu thức nào được so khớp với biểu thức đó.

Người ta có thể hỏi nếu thêm vào -notsẽ không làm cho tất cả các tệp khác bị ẩn khi -prunexuất hiện lại, và câu trả lời là không. Cách thức -prunehoạt động là bất cứ thứ gì, một khi nó được truy cập, các tệp bên dưới thư mục đó sẽ vĩnh viễn bị bỏ qua.

Điều này xuất phát từ một trường hợp sử dụng thực tế, nơi tôi cần gọi yui-archive trên một số tệp được tạo bởi wintersmith, nhưng bỏ qua các tệp khác cần được gửi nguyên trạng.


Lưu ý [1] : Nếu bạn muốn loại trừ /tmp/foo/barvà bạn chạy tìm như thế này " find /tmp \(..." thì bạn phải chỉ định -path /tmp/foo/bar. Mặt khác, nếu bạn chạy tìm thấy như thế này cd /tmp; find . \(...thì bạn phải chỉ định -path ./foo/bar.

225
Reinstate Monica Please 2014-07-04 14:21.

Rõ ràng có một số nhầm lẫn ở đây là cú pháp ưu tiên để bỏ qua một thư mục nên là gì.

Ý kiến ​​GNU

To ignore a directory and the files under it, use -prune

Từ trang tìm người đàn ông GNU

Lý luận

-prunengừng findgiảm dần vào một thư mục. Chỉ cần chỉ định -not -pathsẽ vẫn đi xuống thư mục bị bỏ qua , nhưng -not -pathsẽ sai bất cứ khi nào findkiểm tra từng tệp.

Vấn đề với -prune

-prune thực hiện những gì nó dự định, nhưng vẫn còn một số điều bạn phải lưu ý khi sử dụng nó.

  1. find in thư mục đã lược bớt.

    • ĐÚNG Đó là hành vi dự định, nó chỉ không đi vào nó. Để tránh in toàn bộ thư mục, hãy sử dụng cú pháp loại bỏ nó một cách hợp lý.
  2. -prunechỉ hoạt động với -printvà không có hành động nào khác.

    • KHÔNG ĐÚNG . -prunehoạt động với bất kỳ hành động nào ngoại trừ -delete. Tại sao nó không hoạt động với xóa? Để -deletelàm việc, tìm cần phải duyệt qua thư mục theo thứ tự DFS, vì -deletetrước tiên sẽ xóa các lá, sau đó là bố mẹ của các lá, v.v. Nhưng để chỉ định -prunecó ý nghĩa, findcần phải nhấn vào một thư mục và ngừng giảm dần nó, điều này rõ ràng không có ý nghĩa với -depthhoặc -deletetrên.

Hiệu suất

Tôi thiết lập một bài kiểm tra đơn giản với ba câu trả lời được ủng hộ nhiều nhất cho câu hỏi này (được thay thế -printbằng -exec bash -c 'echo $0' {} \;để hiển thị một ví dụ hành động khác). Kết quả bên dưới

----------------------------------------------
# of files/dirs in level one directories
.performance_test/prune_me     702702    
.performance_test/other        2         
----------------------------------------------

> find ".performance_test" -path ".performance_test/prune_me" -prune -o -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
  [# of files] 3 [Runtime(ns)] 23513814

> find ".performance_test" -not \( -path ".performance_test/prune_me" -prune \) -exec bash -c 'echo "$0"' {} \; .performance_test .performance_test/other .performance_test/other/foo [# of files] 3 [Runtime(ns)] 10670141 > find ".performance_test" -not -path ".performance_test/prune_me*" -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
  [# of files] 3 [Runtime(ns)] 864843145

Phần kết luận

Cả cú pháp của f10bit và cú pháp của Daniel C. Sobral mất trung bình 10-25ms để chạy. Cú pháp của GetFree , không sử dụng -prune, mất 865ms. Vì vậy, có, đây là một ví dụ khá khắc nghiệt, nhưng nếu bạn quan tâm đến thời gian chạy và làm bất cứ điều gì chuyên sâu từ xa, bạn nên sử dụng -prune.

Lưu ý rằng cú pháp của Daniel C. Sobral thực hiện tốt hơn trong hai -prunecú pháp; nhưng, tôi thực sự nghi ngờ đây là kết quả của một số bộ nhớ đệm vì việc chuyển đổi thứ tự mà cả hai đã chạy dẫn đến kết quả ngược lại, trong khi phiên bản không sơ lược luôn chậm nhất.

Tập lệnh thử nghiệm

#!/bin/bash

dir='.performance_test'

setup() {
  mkdir "$dir" || exit 1 mkdir -p "$dir/prune_me/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/w/x/y/z" \
    "$dir/other" find "$dir/prune_me" -depth -type d -exec mkdir '{}'/{A..Z} \;
  find "$dir/prune_me" -type d -exec touch '{}'/{1..1000} \; touch "$dir/other/foo"
}

cleanup() {
  rm -rf "$dir" } stats() { for file in "$dir"/*; do
    if [[ -d "$file" ]]; then count=$(find "$file" | wc -l) printf "%-30s %-10s\n" "$file" "$count" fi done } name1() { find "$dir" -path "$dir/prune_me" -prune -o -exec bash -c 'echo "$0"'  {} \;
}

name2() {
  find "$dir" -not \( -path "$dir/prune_me" -prune \) -exec bash -c 'echo "$0"' {} \; } name3() { find "$dir" -not -path "$dir/prune_me*" -exec bash -c 'echo "$0"' {} \;
}

printf "Setting up test files...\n\n"
setup
echo "----------------------------------------------"
echo "# of files/dirs in level one directories"
stats | sort -k 2 -n -r
echo "----------------------------------------------"

printf "\nRunning performance test...\n\n"

echo \> find \""$dir"\" -path \""$dir/prune_me"\" -prune -o -exec bash -c \'echo \"\$0\"\' {} \\\; name1 s=$(date +%s%N)
name1_num=$(name1 | wc -l) e=$(date +%s%N)
name1_perf=$((e-s)) printf " [# of files] $name1_num [Runtime(ns)] $name1_perf\n\n" echo \> find \""$dir"\" -not \\\( -path \""$dir/prune_me"\" -prune \\\) -exec bash -c \'echo \"\$0\"\' {} \\\;
name2
s=$(date +%s%N) name2_num=$(name2 | wc -l)
e=$(date +%s%N) name2_perf=$((e-s))
printf "  [# of files] $name2_num [Runtime(ns)] $name2_perf\n\n"

echo \> find \""$dir"\" -not -path \""$dir/prune_me*"\" -exec bash -c \'echo \"\$0\"\' {} \\\; name3 s=$(date +%s%N)
name3_num=$(name3 | wc -l) e=$(date +%s%N)
name3_perf=$((e-s)) printf " [# of files] $name3_num [Runtime(ns)] $name3_perf\n\n"

echo "Cleaning up test files..."
cleanup
134
DimiDak 2018-03-16 00:02.

Đây là cái duy nhất làm việc cho tôi.

find / -name MyFile ! -path '*/Directory/*'

Tìm kiếm "MyFile" ngoại trừ "Directory". Nhấn mạnh vào các ngôi sao *.

61
Joshua 2010-11-18 13:01.

Một tùy chọn sẽ là loại trừ tất cả các kết quả có chứa tên thư mục bằng grep. Ví dụ:

find . -name '*.js' | grep -v excludeddir
41
mpapis 2010-11-18 13:22.

Tôi thích -notký hiệu hơn ... nó dễ đọc hơn:

find . -name '*.js' -and -not -path directory
27
Drew Frezell 2010-11-18 13:01.

Sử dụng tùy chọn -prune. Vì vậy, một cái gì đó như:

find . -type d -name proc -prune -o -name '*.js'

'-Type d -name proc -prune' chỉ tìm kiếm các thư mục có tên proc để loại trừ.
Toán tử '-o' là một toán tử 'HOẶC'.

22
wisbucky 2017-11-17 14:38.

-prunechắc chắn hoạt động và là câu trả lời tốt nhất vì nó ngăn chặn việc giảm xuống đồng tiền mà bạn muốn loại trừ. -not -pathmà vẫn tìm kiếm dir bị loại trừ, nó chỉ không in ra kết quả, điều này có thể là một vấn đề nếu dir bị loại trừ được gắn kết khối lượng mạng hoặc bạn không có quyền.

Phần khó khăn là nó findrất đặc biệt về thứ tự của các đối số, vì vậy nếu bạn không hiểu chúng vừa phải, lệnh của bạn có thể không hoạt động. Thứ tự của các đối số thường như vậy:

find {path} {options} {action}

{path}: Đặt tất cả các đối số liên quan đến đường dẫn trước, như . -path './dir1' -prune -o

{options}: Tôi thành công nhất khi đặt -name, -iname, etclàm lựa chọn cuối cùng trong nhóm này. Ví dụ-type f -iname '*.js'

{action}: Bạn sẽ muốn thêm -printkhi sử dụng-prune

Đây là một ví dụ hoạt động:

# setup test
mkdir dir1 dir2 dir3
touch dir1/file.txt; touch dir1/file.js
touch dir2/file.txt; touch dir2/file.js
touch dir3/file.txt; touch dir3/file.js

# search for *.js, exclude dir1
find . -path './dir1' -prune -o -type f -iname '*.js' -print

# search for *.js, exclude dir1 and dir2
find . \( -path './dir1' -o -path './dir2' \) -prune -o -type f -iname '*.js' -print
16
user1882879 2016-01-19 07:06.

Đây là định dạng tôi đã sử dụng để loại trừ một số đường dẫn:

$ find ./ -type f -name "pattern" ! -path "excluded path" ! -path "excluded path"

Tôi đã sử dụng điều này để tìm tất cả các tệp không có trong đường dẫn ". *":

$ find ./ -type f -name "*" ! -path "./.*" ! -path "./*/.*"
13
Wolfgang Fahl 2017-08-30 18:05.

Cách tiếp cận -path -prune cũng hoạt động với các ký tự đại diện trong đường dẫn. Đây là một câu lệnh find sẽ tìm các thư mục cho một máy chủ git phục vụ nhiều kho lưu trữ git, loại bỏ các thư mục nội bộ git:

find . -type d \
   -not \( -path */objects -prune \) \
   -not \( -path */branches -prune \) \
   -not \( -path */refs -prune \) \
   -not \( -path */logs -prune \) \
   -not \( -path */.git -prune \) \
   -not \( -path */info -prune \) \
   -not \( -path */hooks -prune \)  
12
Istopopoki 2018-03-08 00:20.

Có rất nhiều câu trả lời hay, tôi chỉ mất chút thời gian để hiểu từng phần tử của lệnh dùng để làm gì và logic đằng sau nó.

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

find sẽ bắt đầu tìm các tệp và thư mục trong thư mục hiện tại, do đó find ..

Các -otùy chọn là viết tắt của một logic OR và tách hai phần của lệnh:

[ -path ./misc -prune ] OR [ -name '*.txt' -print ]

Bất kỳ thư mục hoặc tệp nào không phải là thư mục ./misc sẽ không vượt qua bài kiểm tra đầu tiên -path ./misc. Nhưng chúng sẽ được kiểm tra đối với biểu thức thứ hai. Nếu tên của họ tương ứng với mẫu *.txtmà họ được in, vì -printtùy chọn.

When find reaches the ./misc directory, this directory only satisfies the first expression. So the -prune option will be applied to it. It tells the find command to not explore that directory. So any file or directory in ./misc will not even be explored by find, will not be tested against the second part of the expression and will not be printed.

10
JBENOIT 2014-03-20 01:03.

To exclude multiple directories:

find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" \)

To add directories, add -o -path "./dirname/*":

find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" -o -path "./dir3/*"\)

But maybe you should use a regular expression, if there are many directories to exclude.

8
james dupin 2013-12-10 00:12.

For a working solution (tested on Ubuntu 12.04 (Precise Pangolin))...

find ! -path "dir1" -iname "*.mp3"

will search for MP3 files in the current folder and subfolders except in dir1 subfolder.

Use:

find ! -path "dir1" ! -path "dir2" -iname "*.mp3"

...to exclude dir1 AND dir2

7
cycollins 2019-09-04 11:35.

a good trick for avoiding printing the pruned directories is to use -print (works for -exec as well) after the right side of the -or after -prune. For example, ...

find . -path "*/.*" -prune -or -iname "*.j2"

will print the path of all files beneath the current directory with the `.j2" extension, skipping all hidden directories. Neat. But it will also print the print the full path of each directory one is skipping, as noted above. However, the following does not, ...

find . -path "*/.*" -prune -or -iname "*.j2" -print

because logically there's a hidden -and after the -iname operator and before the -print. This binds it to the right part of the -or clause due to boolean order of operations and associativity. But the docs say there's a hidden -print if it (or any of its cousins ... -print0, etc) is not specified. So why isn't the left part of the -or printing? Apparently (and I didn't understand this from my first reading the man page), that is true if there there is no -print -or -exec ANYWHERE, in which case, -print is logically sprinkled around such that everything gets printed. If even ONE print-style operation is expressed in any clause, all those hidden logical ones go away and you get only what you specify. Now frankly, I might have preferred it the other way around, but then a find with only descriptive operators would apparently do nothing, so I guess it makes sense as it is. As mentioned above, this all works with -exec as well, so the following gives a full ls -la listing for each file with the desired extension, but not listing the first level of each hidden directory, ...

find . -path "*/.*" -prune -or -iname "*.j2" -exec ls -la -- {} +

For me (and others on this thread), find syntax gets pretty baroque pretty quickly, so I always throw in parens to make SURE I know what binds to what, so I usually create a macro for type-ability and form all such statements as ...

find . \( \( ... description of stuff to avoid ... \) -prune \) -or \
\( ... description of stuff I want to find ... [ -exec or -print] \)

It's hard to go wrong by setting up the world into two parts this way. I hope this helps, though it seems unlikely for anyone to read down to the 30+th answer and vote it up, but one can hope. :-)

6
The Archetypal Paul 2010-11-18 13:01.
find . -name '*.js' -\! -name 'glob-for-excluded-dir' -prune
5
Funkodebat 2014-08-30 10:41.
find -name '*.js' -not -path './node_modules/*' -not -path './vendor/*'

seems to work the same as

find -name '*.js' -not \( -path './node_modules/*' -o -path './vendor/*' \)

and is easier to remember IMO.

5
Siju V 2015-07-21 17:52.

You can use the prune option to achieve this. As in for example:

find ./ -path ./beta/* -prune -o -iname example.com -print

Or the inverse grep “grep -v” option:

find -iname example.com | grep -v beta

You can find detailed instructions and examples in Linux find command exclude directories from searching.

5
supersan 2020-02-28 08:43.

You can also use regular expressions to include / exclude some files /dirs your search using something like this:

find . -regextype posix-egrep -regex ".*\.(js|vue|s?css|php|html|json)$" -and -not -regex ".*/(node_modules|vendor)/.*" 

This will only give you all js, vue, css, etc files but excluding all files in the node_modules and vendor folders.

4
Sixro 2013-09-24 08:25.

None of previous answers is good on Ubuntu. Try this:

find . ! -path "*/test/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"

I have found this here

4
Victoria Stuart 2018-09-28 07:51.

TLDR: understand your root directories and tailor your search from there, using the -path <excluded_path> -prune -o option. Do not include a trailing / at the end of the excluded path.

Example:

find / -path /mnt -prune -o -name "*libname-server-2.a*" -print


To effectively use the find I believe that it is imperative to have a good understanding of your file system directory structure. On my home computer I have multi-TB hard drives, with about half of that content backed up using rsnapshot (i.e., rsync). Although backing up to to a physically independent (duplicate) drive, it is mounted under my system root (/) directory: /mnt/Backups/rsnapshot_backups/:

/mnt/Backups/
└── rsnapshot_backups/
    ├── hourly.0/
    ├── hourly.1/
    ├── ...
    ├── daily.0/
    ├── daily.1/
    ├── ...
    ├── weekly.0/
    ├── weekly.1/
    ├── ...
    ├── monthly.0/
    ├── monthly.1/
    └── ...

The /mnt/Backups/rsnapshot_backups/ directory currently occupies ~2.9 TB, with ~60M files and folders; simply traversing those contents takes time:

## As sudo (#), to avoid numerous "Permission denied" warnings:

time find /mnt/Backups/rsnapshot_backups | wc -l
60314138    ## 60.3M files, folders
34:07.30    ## 34 min

time du /mnt/Backups/rsnapshot_backups -d 0
3112240160  /mnt/Backups/rsnapshot_backups    ## 3.1 TB
33:51.88    ## 34 min

time rsnapshot du    ## << more accurate re: rsnapshot footprint
2.9T    /mnt/Backups/rsnapshot_backups/hourly.0/
4.1G    /mnt/Backups/rsnapshot_backups/hourly.1/
...
4.7G    /mnt/Backups/rsnapshot_backups/weekly.3/
2.9T    total    ## 2.9 TB, per sudo rsnapshot du (more accurate)
2:34:54          ## 2 hr 35 min

Thus, anytime I need to search for a file on my / (root) partition, I need to deal with (avoid if possible) traversing my backups partition.


EXAMPLES

Among the approached variously suggested in this thread (How to exclude a directory in find . command), I find that searches using the accepted answer are much faster -- with caveats.

Solution 1

Let's say I want to find the system file libname-server-2.a, but I do not want to search through my rsnapshot backups. To quickly find a system file, use the exclude path /mnt (i.e., use /mnt, not /mnt/, or /mnt/Backups, or ...):

## As sudo (#), to avoid numerous "Permission denied" warnings:

time find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a
real    0m8.644s              ## 8.6 sec  <<< NOTE!
user    0m1.669s
 sys    0m2.466s

## As regular user (victoria); I also use an alternate timing mechanism, as
## here I am using 2>/dev/null to suppress "Permission denied" warnings:

$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt -prune -o \
    -name "*libname-server-2.a*" -print; END="$(date +"%s")"; \ TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 3 sec     ## ~3 sec  <<< NOTE!

... finds that file in just a few seconds, while this take much longer (appearing to recurse through all of the "excluded" directories):

## As sudo (#), to avoid numerous "Permission denied" warnings:

time find / -path /mnt/ -prune -o -name "*libname-server-2.a*" -print
find: warning: -path /mnt/ will not match anything because it ends with /.
/usr/lib/libname-server-2.a
real    33m10.658s            ## 33 min 11 sec (~231-663x slower!)
user    1m43.142s
 sys    2m22.666s

## As regular user (victoria); I also use an alternate timing mechanism, as
## here I am using 2>/dev/null to suppress "Permission denied" warnings:

$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt/ -prune -o \ -name "*libname-server-2.a*" -print; END="$(date +"%s")"; \
    TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 1775 sec    ## 29.6 min

Solution 2

The other solution offered in this thread (SO#4210042) also performs poorly:

## As sudo (#), to avoid numerous "Permission denied" warnings:

time find / -name "*libname-server-2.a*" -not -path "/mnt"
/usr/lib/libname-server-2.a
real    33m37.911s            ## 33 min 38 sec (~235x slower)
user    1m45.134s
 sys    2m31.846s

time find / -name "*libname-server-2.a*" -not -path "/mnt/*"
/usr/lib/libname-server-2.a
real    33m11.208s            ## 33 min 11 sec
user    1m22.185s
 sys    2m29.962s

SUMMARY | CONCLUSIONS

Use the approach illustrated in "Solution 1"

find / -path /mnt -prune -o -name "*libname-server-2.a*" -print

i.e.

... -path <excluded_path> -prune -o ...

noting that whenever you add the trailing / to the excluded path, the find command then recursively enters (all those) /mnt/* directories -- which in my case, because of the /mnt/Backups/rsnapshot_backups/* subdirectories, additionally includes ~2.9 TB of files to search! By not appending a trailing / the search should complete almost immediately (within seconds).

"Solution 2" (... -not -path <exclude path> ...) likewise appears to recursively search through the excluded directories -- not returning excluded matches, but unnecessarily consuming that search time.


Searching within those rsnapshot backups:

To find a file in one of my hourly/daily/weekly/monthly rsnapshot backups):

$ START="$(date +"%s")" && find 2>/dev/null /mnt/Backups/rsnapshot_backups/daily.0 -name '*04t8ugijrlkj.jpg'; END="$(date +"%s")"; TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/mnt/Backups/rsnapshot_backups/daily.0/snapshot_root/mnt/Vancouver/temp/04t8ugijrlkj.jpg
find command took 312 sec   ## 5.2 minutes: despite apparent rsnapshot size
                            ## (~4 GB), it is in fact searching through ~2.9 TB)

Excluding a nested directory:

Here, I want to exclude a nested directory, e.g. /mnt/Vancouver/projects/ie/claws/data/* when searching from /mnt/Vancouver/projects/:

$ time find . -iname '*test_file*'
./ie/claws/data/test_file
./ie/claws/test_file
0:01.97

$ time find . -path '*/data' -prune -o -iname '*test_file*' -print
./ie/claws/test_file
0:00.07

Aside: Adding -print at the end of the command suppresses the printout of the excluded directory:

$ find / -path /mnt -prune -o -name "*libname-server-2.a*"
/mnt
/usr/lib/libname-server-2.a

$ find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a
4
Richard Gomes 2020-05-30 01:01.
find . \( -path '.**/.git' -o -path '.**/.hg' \) -prune -o -name '*.js' -print

The example above finds all *.js files under the current directory, excluding folders .git and .hg, does not matter how deep these .git and .hg folders are.

Note: this also works:

find . \( -path '.*/.git' -o -path '.*/.hg' \) -prune -o -name '*.js' -print

but I prefer the ** notation for consistency with some other tools which would be off topic here.

3
Lemmings19 2013-05-31 06:56.

I was using find to provide a list of files for xgettext, and wanted to omit a specific directory and its contents. I tried many permutations of -path combined with -prune but was unable to fully exclude the directory which I wanted gone.

Although I was able to ignore the contents of the directory which I wanted ignored, find then returned the directory itself as one of the results, which caused xgettext to crash as a result (doesn't accept directories; only files).

My solution was to simply use grep -v to skip the directory that I didn't want in the results:

find /project/directory -iname '*.php' -or -iname '*.phtml' | grep -iv '/some/directory' | xargs xgettext

Whether or not there is an argument for find that will work 100%, I cannot say for certain. Using grep was a quick and easy solution after some headache.

3
jiahut 2015-03-18 21:56.

This is suitable for me on a Mac:

find . -name *.php -or -path "./vendor" -prune -or -path "./app/cache" -prune

It will exclude vendor and app/cache dir for search name which suffixed with php.

3
JaredTS486 2017-11-17 09:56.

For those of you on older versions of UNIX who cannot use -path or -not

Tested on SunOS 5.10 bash 3.2 and SunOS 5.11 bash 4.4

find . -type f -name "*" -o -type d -name "*excluded_directory*" -prune -type f
2
go2null 2015-01-27 08:17.

how-to-use-prune-option-of-find-in-sh is an excellent answer by Laurence Gonsalves on how -prune works.

And here is the generic solution:

find /path/to/search                    \
  -type d                               \
    \( -path /path/to/search/exclude_me \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -prune                              \
  -o                                    \
  -type f -name '*\.js' -print

To avoid typing /path/to/seach/ multiple times, wrap the find in a pushd .. popd pair.

pushd /path/to/search;                  \
find .                                  \
  -type d                               \
    \( -path ./exclude_me               \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -prune                              \
  -o                                    \
  -type f -name '*\.js' -print;         \
 popd
2
adrianTNT 2018-03-28 00:26.

For what I needed it worked like this, finding landscape.jpg in all server starting from root and excluding the search in /var directory:

find / -maxdepth 1 -type d | grep -v /var | xargs -I '{}' find '{}' -name landscape.jpg

find / -maxdepth 1 -type d lists all directories in /

grep -v /var excludes `/var' from the list

xargs -I '{}' find '{}' -name landscape.jpg execute any command, like find with each directory/result from list

2
EIIPII 2020-02-26 05:29.

The following commands works:

find . -path ./.git -prune -o -print

If You have a problem with find, use the -D tree option to view the expression analysis information.

find -D tree . -path ./.git -prune -o -print

Or the -D all, to see all the execution information.

find -D all . -path ./.git -prune -o -print
1
Ivan Ivanovich 2015-04-23 00:47.

I found the functions name in C sources files exclude *.o and exclude *.swp and exclude (not regular file) and exclude dir output with this command:

find .  \( ! -path "./output/*" \) -a \( -type f \) -a \( ! -name '*.o' \) -a \( ! -name '*.swp' \) | xargs grep -n soc_attach
1
Alberto 2015-08-28 22:25.

Better use the exec action than the for loop:

find . -path "./dirtoexclude" -prune \
    -o -exec java -jar config/yuicompressor-2.4.2.jar --type js '{}' -o '{}' \;

The exec ... '{}' ... '{}' \; will be executed once for every matching file, replacing the braces '{}' with the current file name.

Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation*.


Notes

* From the EXAMPLES section of the find (GNU findutils) 4.4.2 man page

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Xem đoạn giới thiệu cho bộ phim chuyển thể đầy khói lửa, có sự góp mặt của ngôi sao Edward Norton từ phim Motherless Brooklyn của Jonathan Lethem

Xem đoạn giới thiệu cho bộ phim chuyển thể đầy khói lửa, có sự góp mặt của ngôi sao Edward Norton từ phim Motherless Brooklyn của Jonathan Lethem

Edward Norton đã muốn đưa cuốn tiểu thuyết Motherless Brooklyn của Jonathan Lethem's Joycean 1999 lên màn ảnh kể từ khi nó được xuất bản. Bây giờ, 20 năm sau, một đoạn giới thiệu đã xuất hiện cho câu chuyện sôi nổi, đưa câu chuyện của Lethem trở lại những năm 1950 với rất nhiều gương mặt quen thuộc.

Cách dễ dàng chọn không tham gia trọng tài ràng buộc thẻ Apple

Cách dễ dàng chọn không tham gia trọng tài ràng buộc thẻ Apple

Có thích thú khi sử dụng Thẻ Apple mới của bạn không? Trước khi bạn bắt đầu chi tiêu, có một nhiệm vụ bổ sung cần xem xét: chọn không tham gia trọng tài ràng buộc. Bạn sẽ phát hiện ra các điều khoản trọng tài ràng buộc trong nhiều thỏa thuận tài chính vì nó giúp ngăn các ngân hàng và đối tác kinh doanh của họ không phải ra tòa.

Những người chơi Fortnite World Cup không ghi bàn có cảm giác hài hước về điều đó

Những người chơi Fortnite World Cup không ghi bàn có cảm giác hài hước về điều đó

Điểm số tại vòng chung kết Fortnite World Cup Solo hôm nay là rất lớn, với người chiến thắng Bugha ghi được nhiều hơn 26 điểm so với người về thứ hai là Psalm. Nhưng không phải ai cũng có thể giành chiến thắng: Bốn cầu thủ ra về với 0 điểm, nhưng — ít nhất là trên Twitter — họ là những người thể thao tốt về điều đó.

Báo cáo: Cánh cửa tuyển sinh có thể đã mở cho các ứng viên UCLA có mối quan hệ có ảnh hưởng

Báo cáo: Cánh cửa tuyển sinh có thể đã mở cho các ứng viên UCLA có mối quan hệ có ảnh hưởng

Huấn luyện viên trưởng của bộ môn thể dục dụng cụ UCLA Valorie Kondos-Field theo dõi Katelyn Ohashi thi đấu thăng bằng trong trận gặp Stanford tại Pauley Pavilion vào ngày 10 tháng 3 năm 2019 ở Los Angeles, California. Vụ bê bối gian lận tuyển sinh đại học tiết lộ các chi tiết của một quá trình chính thức hóa để đưa những đứa trẻ thất bại của các gia đình giàu có và nổi tiếng vào các trường đại học đáng tin cậy và danh tiếng, sử dụng một "cửa phụ" đắt tiền cho các bậc cha mẹ mà sự giàu có của họ khiến họ không có cơ hội. chỉ cần tài trợ cho một cánh mới trong khuôn viên trường.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Tầm nhìn đám mây phi tập trung của DFINITY Blockchain

Lưu ý của người biên tập: Bạn đang xem tài liệu lỗi thời từ blog DFINITY đang được bảo quản cho mục đích lưu trữ.

Tầm nhìn đám mây phi tập trung của DFINITY Blockchain

Bài đăng này khám phá tầm nhìn về đám mây phi tập trung của nhóm DFINITY và cách nó liên quan đến các nhà cung cấp blockchain truyền thống và đám mây hiện có như Amazon Web Services. Các minh chứng về công nghệ DFINITY được áp dụng bởi một mạng lưới quy mô lớn sẽ được thực hiện vào mùa thu năm 2017, sau đó sẽ được gây quỹ Chính cho quỹ hỗ trợ phi lợi nhuận, với mạng “đám mây mở” dự kiến ​​sẽ ra mắt vào đầu mùa hè năm 2018 .

Language