如何用find命令查找.hs文件并排除sub目录及含test的文件
Got it, let's fix this for you—you're right, this shouldn't be as complicated as it feels when you're first figuring out find's quirks.
First, let's break down why your previous attempts didn't work:
- Your first command
find . -name "*.hs" -not -name '*sub*' -not -name "*test*"only excludes files whose names contain "sub", not the entiresubdirectory and everything inside it. So files insidesub/that end with.hswould still show up, as long as their names don't have "sub" in them. - Your second command
find . -name "*.hs" -not -path '/sub' -not -name "*test*"uses an absolute path/subwhich doesn't match the relative path from your current directory. Even if you fixed it to./sub, it would only exclude the directory itself, not the files inside it.
The Simple, Efficient Solution Using -prune
The cleanest way to skip an entire directory (instead of filtering its files after finding them) is with -prune. Here's the command you need:
find . -type d -name "sub" -prune -o -name "*.hs" -not -name "*test*" -print
Let's break this down piece by piece so you understand what's happening:
.: Start searching from the current directory-type d -name "sub" -prune: Look for directories namedsub, and when we find them, skip (prune) them entirely—we won't even look inside them for files-o: Short for "or"—if the previous condition (finding thesubdirectory) isn't met, run the next part-name "*.hs": Match any file ending with.hs-not -name "*test*": Exclude any file whose name contains "test"-print: Print the matching files (somefindversions do this by default, but adding it makes the behavior explicit and consistent across systems)
Alternative: Using -path to Filter Results
If you prefer a more straightforward (though slightly less efficient) approach, you can use -path to exclude any file inside the sub directory:
find . -name "*.hs" -not -name "*test*" -not -path "./sub/*"
This works by finding all .hs files, then filtering out any that are inside sub/ and any with "test" in their name. The downside here is that find still has to traverse the entire sub directory first before discarding the results—so if sub is large, -prune is better because it avoids that work entirely.
Either way, both commands will give you exactly what you want: all .hs files in your current directory and its subdirectories (except sub/), with no files that have "test" in their name.
内容的提问来源于stack exchange,提问作者user855443

