查看文件夹结构中是否存在给定扩展名的任何文件(不包括一些目录)

查看文件夹结构中是否存在给定扩展名的任何文件(不包括一些目录)

我正在尝试将一个脚本放在一起,我可以在 CI 构建中使用它,该脚本将用作我的 Typescript Mono-repo 项目的 linter。

我想要完成的是查看.js项目/包存储库中是否有任何文件,但避免使用node_modules它们所在的文件夹以及common文件夹及其所有子目录和文件。

文件结构是这样的

project/
├── apps/
│   ├── app1
├── common/
│   ├── folder1
│   ├── folder1
│   ├── etc
├── lib/
│   ├── lib1
├── services/
│   ├── service1

services,lib,apps所有 npm 项目的子目录。

目前我尝试过的一些不同尝试包括:

find . \( ! -name node_modules \) -o \( ! -path common -prune \) -name "*.js" -print

但即使我在或任何其他列入白名单的文件夹中创建虚拟.js文件,它似乎也不会返回任何内容。/project

此尝试似乎是最接近的,因为它打印出了测试文件,但它也找到了 中的文件common,但它应该被列入黑名单。

find . -type d \( -path common -o -name node_modules \) -prune -false -o -name '*.js'

该运行的输出:

./test.js
./common/temp/pnpmfile.js
./common/temp/pnpm-store/2/registry.npmjs.org/ipaddr.js
./common/config/rush/pnpmfile.js
./common/scripts/install-run.js
./common/scripts/install-run-rushx.js
./common/scripts/install-run-rush.js
./services/test.js

我想要此脚本的总体目标是,如果在白名单目录中没有找到文件,则退出 0;如果在黑名单目录之外找到文件,.js则返回退出 1 。.js

我是个新手,对 shell 命令缺乏经验,所以任何帮助将不胜感激,提前谢谢您!

答案1

你的命令几乎是正确的。修复它:

find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print

这会修剪任何名为node_modules或 位于 的内容./common。请注意,使用的路径名-path是以顶级搜索路径为开头的路径,因此.在这种情况下必须以开头。

-false使用的不是必需的。如果node_modules或 也与您之后的测试./common相匹配,则需要它。这也是您可能想要使用 的时候,但现在您不必这样做。-name-o-type d

测试:

$ tree
.
|-- common
|   `-- file.js
|-- dir
|   |-- common
|   |   `-- file.js
|   |-- file.js
|   `-- node_modules
|       `-- file.js
`-- node_modules
    `-- file.js

5 directories, 5 files
$ find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print
./dir/file.js
./dir/common/file.js

找到该文件./dir/common/file.js是因为它位于未修剪的目录中(common仅当它位于当前目录的正下方时才被修剪)。


别处,看来你只想看看有没有任何*.js未修剪目录中匹配的文件。您可以通过以下方式有效地做到这一点

if find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -exec echo . \; | grep -q .
then
    echo there are JS files
else
    echo there are no JS files
fi

在这里,每当我找到文件时,我都会输出一个点(可以是任何字符),并用于grep -q .检测find.当发现某些内容时,grep将以零退出状态终止,表示“成功”,并且该if语句将采用第一个分支。find一旦该命令尝试向grep不再监听的管道写入另一个点,该命令就会终止。

答案2

如果您使用 -path ,请使用完全声明的路径,例如./common或用于-name匹配找到的树中的任何位置。

这个命令对我来说是一个测试。

find . -type d \( -name common -o -name node_modules \) -prune -false -o -name '*.js'

答案3

在查看和测试上述一些答案后,我最终使用的命令是:

find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print

我必须保留 arg 的原因-print是我发现运行它时得到的输出没有将-print某些文件夹显示为如下输出:

./common
./lib/trader-sdk/node_modules
./lib/is-ticker-symbol/node_modules
./apps/cron-app/node_modules
./services/templating-service/node_modules
./services/api-service/node_modules
./services/trading-services/node_modules
./services/sentiment-service/node_modules

但是当我添加-printarg 时,输出什么也没有,这是在这种情况下所期望的。

奖励:这是最后一个用例,一个基本脚本,它将检查我的 TypeScript mono-repo,以确保没有人尝试将任何构建.js文件合并到 master 中。

#!/bin/bash

jsFiles=$(find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print)

if [ -z "$jsFiles" ]
then
      echo "No JS files found, free to proceed"
      exit 0
else
      echo "JS files found, unable to proceed"
      exit 1
fi

相关内容