shell 递归查找文件,排除具有特定子字符串的子文件夹

agyaoht7  于 2023-03-09  发布在  Shell
关注(0)|答案(2)|浏览(156)

我需要获得所有路径,其中有一个特定的文件:

find apps  -type f -name "project.json"

这将返回类似于

apps/sub/frontend-e2e/project.json
apps/sub/frontend/project.json
apps/sub/backend/project.json

但我想排除最后一个文件夹中包含-e2e的所有路径。
我试过

find apps  -type f -name "project.json" -not \( -path "*-e2e" -prune \)

我还需要从每个路径的开头和结尾删除apps//project.json,所以结果应该是:

sub/frontend
sub/backend

在JS我会做

glob.sync('apps/**/project.json', {
    ignore: ['apps/**/*-e2e/project.json']
}).map((path) => {
    // do replacements
})
siotufzp

siotufzp1#

像这样:
$ tree apps/
apps/
└── sub
    ├── backend
    │   └── project.json
    ├── frontend
    │   └── project.json
    └── frontend-e2e
        └── project.json

4 directories, 3 files

$ find ./apps -not -path '*-e2e/project.json' -name project.json -printf '%h\n'
apps/sub/frontend
apps/sub/backend
yv5phkfx

yv5phkfx2#

如果您已经安装了Bash 4.3(2014年发布)或更高版本,请尝试以下Shellcheck-clean代码:

shopt -s dotglob extglob globstar nullglob
for path in apps/**/!(*-e2e)/project.json; do
    p=${path#*/}
    printf '%s\n' "${p%/*}"
done
  • shopt -s ...启用代码所需的一些Bash设置:
  • dotglob允许全局匹配以.开始的文件和目录。默认情况下,find显示此类文件。
  • extglob支持“扩展的globbing”(包括像!(*-e2e)这样的模式),参见glob - Greg's Wiki中的extglob部分。
  • globstar允许使用**通过目录树递归匹配路径。此选项是随Bash 4.0引入的,但在4.3之前的版本中使用很危险,因为它遵循符号链接。
  • nullglob使glob在没有匹配项时扩展为空(否则扩展为glob模式本身,这在程序中几乎没有用)。
  • 请参见移除字符串的一部分(BashFAQ/100(如何在bash中进行字符串操作?)),了解${path#*/}${p%/*}的解释。
  • 请参阅Why is printf better than echo?的公认的、优秀的答案,以了解我为什么使用printf而不是echo来打印输出。

请注意,对于路径apps/project.json,这段代码不会输出任何内容,在这种情况下,您希望输出什么也不清楚。

相关问题