=Start=
缘由:
简单整理一下结论,方便后面有需要的时候参考。
正文:
参考解答:
question:
How do I exclude a specific directory when searching for *.js files using find?
在使用 find 搜索 *.js 文件时,我如何排除特定目录?
find . -name '*.js'
answer(s):
find -name "*.js" -not -path "./directory/*"
#这个find命令还是遍历了你不想遍历的目录,因此如果希望速度快,就是用 -prune 选项
find . -path ./dir1 -prune -false -o -name "*.txt"
#排除1个目录
find . -type d \( -path ./dir1 -o -path ./dir2 -o -path ./dir3 \) -prune -false -o -name "*.txt"
#排除多个目录
find . -not \( -path ./dir1 -prune \) -name "*.txt"
#符合预期,且如果你关心运行时间,并做任何远程密集的事情,你应该使用-prune。find . -not \( -path ./dir1 -prune \) -not \( -path ./dir2 -prune \) -name "*.txt"
#符合预期,且如果你关心运行时间,并做任何远程密集的事情,你应该使用-prune。
# 测试的文件目录结构
$ find . -type f -iname "*.txt"
./dir2/a.txt
./dir3/a.txt
./dir1/a.txt
./a.txt
# 这是 GetFree 的答案
$ find . -type f -iname "*.txt" -not -path "./dir1/*" #符合预期,起码结果里没有匹配的项目了(但是实际效果最慢,如果目录不大文件不多,也可以使用)
./dir2/a.txt
./dir3/a.txt
./a.txt
# 这是 f10bit 的答案
$ find . -type d \( -path ./dir1 -o -path ./dir2 -o -path ./dir3 \) -prune -o -name "*.txt" #不符合预期(但实际上是没问题的,它只是把不扫描的目录列出来了而已)
./dir2
./dir3
./dir1
./a.txt
# 【nice,推荐】这是在 f10bit 的答案下根据评论微调而成的
$ find . -type d \( -path ./dir1 -o -path ./dir2 -o -path ./dir3 \) -prune -false -o -name "*.txt" #符合预期,在【-prune】后面添加上【-false】即可
./a.txt
# 【nice,推荐】这是 Daniel C. Sobral 的答案,运行速度快,且可读性很高
$ find . -not \( -path ./dir1 -prune \) -name "*.txt" #符合预期,且如果你关心运行时间,并做任何远程密集的事情,你应该使用-prune。
./dir2/a.txt
./dir3/a.txt
./a.txt
# you can also exclude multiple paths
$ find . -not \( -path ./dir1 -prune \) -not \( -path ./dir2 -prune \) -name "*.txt" #符合预期,且如果你关心运行时间,并做任何远程密集的事情,你应该使用-prune。
./dir3/a.txt
./a.txt
# Reinstate Monica 答案里的测试脚本
#!/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
参考链接:
How do I exclude a directory when using find
?
https://stackoverflow.com/questions/4210042/how-do-i-exclude-a-directory-when-using-find
Linux下用find命令一次查找多种类型的文件
https://ixyzero.com/blog/archives/2510.html
=END=