Linux 使用 find 命令但排除两个目录中的文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14132210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 18:10:45  来源:igfitidea点击:

Use find command but exclude files in two directories

linuxshellunixfind

提问by Hanfei Sun

I want to find files that end with _peaks.bed, but exclude files in the tmpand scriptsfolders.

我想查找以 结尾的文件_peaks.bed,但排除tmpscripts文件夹中的文件。

My command is like this:

我的命令是这样的:

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

But it didn't work. The files in tmpand scriptfolder will still be displayed.

但它没有用。中的文件tmpscript文件夹仍将显示。

Does anyone have ideas about this?

有没有人对此有想法?

采纳答案by sampson-chen

Here's how you can specify that with find:

您可以通过以下方式指定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 findthat 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/
  • find .- 从当前工作目录开始查找(默认递归)
  • -type f- 指定find您只想要结果中的文件
  • -name "*_peaks.bed"- 查找名称以 结尾的文件 _peaks.bed
  • ! -path "./tmp/*"- 排除所有路径以 ./tmp/
  • ! -path "./scripts/*"- 同时排除所有路径以 ./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 -nameoption only considers the basename, where as -pathconsiders the entire path =)

您非常接近,该-name选项仅考虑基本名称,其中 as-path考虑整个路径 =)

回答by alex

Here is one way you could do it...

这是你可以做到的一种方法......

find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"

回答by DrC

Try something like

尝试类似的东西

find . \( -type f -name \*_peaks.bed -print \) -or \( -type d -and \( -name tmp -or -name scripts \) -and -prune \)

and don't be too surprised if I got it a bit wrong. If the goal is an exec (instead of print), just substitute it in place.

如果我弄错了也不要太惊讶。如果目标是 exec (而不是打印),只需将其替换到位。

回答by Al3x

for me, this solution didn't worked on a command exec with find, don't really know why, so my solution is

对我来说,这个解决方案在带有 find 的命令 exec 上不起作用,真的不知道为什么,所以我的解决方案是

find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;

Explanation:same as sampson-chen one with the additions of

说明:与 sampson-chen 相同,但添加了

-prune - ignore the proceding path of ...

-prune - 忽略...的处理路径

-o - Then if no match print the results, (prune the directories and print the remaining results)

-o - 如果没有匹配,则打印结果,(修剪目录并打印剩余的结果)

18:12 $ mkdir a b c d e
18:13 $ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
18:13 $ find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;

gzip: . is a directory -- ignored
gzip: ./a is a directory -- ignored
gzip: ./b is a directory -- ignored
gzip: ./c is a directory -- ignored
./c/3:    0.0% -- replaced with ./c/3.gz
gzip: ./d is a directory -- ignored
./d/4:    0.0% -- replaced with ./d/4.gz
gzip: ./e is a directory -- ignored
./e/5:    0.0% -- replaced with ./e/5.gz
./e/a:    0.0% -- replaced with ./e/a.gz
./e/b:    0.0% -- replaced with ./e/b.gz

回答by Hymany Jiang

You can try below:

你可以试试下面的:

find ./ ! \( -path ./tmp -prune \) ! \( -path ./scripts -prune \) -type f -name '*_peaks.bed'