我需要编写一个Bash脚本(最好是单行脚本)来查找当前目录下的所有子目录,这些目录包含任何带有特定文件扩展名的文件,即.tf
。棘手的是,一个文件夹中可能有多个.tf
文件,并且我需要这些文件夹-不是文件名。
例如,假设我的目录内容如下所示:
.
├── docs
│ ├── README.md
│ └── diagram.png
├── project
│ └── main.py
├── Makefile
├── terraform
│ ├── environments
│ │ ├── prod
│ │ │ └── main.tf
│ │ └── staging
│ │ └── main.tf
│ └── module
│ ├── ecs.tf
│ ├── rds.tf
│ ├── s3.tf
│ ├── security_group.tf
│ ├── sqs.tf
│ └── variable.tf
├── tests
| └── test_main.py
└── .terraform
└── ignore_me.tf
在这种情况下,我希望命令返回terraform/module
,terraform/environments/prod
和terraform/environments/staging
。我还需要一种方法来过滤掉某些不应包含的目录。在上面的示例中,我没有包含点文件目录.terraform
。
我已经知道如何编写以下find命令,该命令可以自行找到.tf
文件:
find . -name '*.tf' -not -path '*.terraform*'
但是我不确定如何编写命令来查找包含那些文件的目录。
答案 0 :(得分:4)
您可以使用find的@EndDate
操作仅打印目录名称,然后删除重复项:
-printf
find . -name '*.tf' -not -path '*.terraform*' -printf '%h\n' | sort -u
打印出包含匹配文件的目录名称,而末尾的-printf '%h\n'
则删除重复的文件。
答案 1 :(得分:1)
尝试一下:
shopt -s globstar
echo **/*.tf | xargs dirname | sort -u
答案 2 :(得分:1)
此find
命令也应该起作用:
find . -type d -not -path '*/.terraform*' \
-exec bash -c 'shopt -s failglob; ( : "$1"/*.tf ) 2>/dev/null && echo "$1"' - {} \;
failglob
如果全局模式失败,则返回失败。find
命令扫描当前路径中的每个目录,bash -c
检查每个目录中是否存在*.tf
个文件。答案 3 :(得分:0)
您可以这样做:
shopt -s globstar # to enable support for **
for i in **/*.tf; do echo "${i%/*}"; done | sort -u
如果您尚未启用**
,则shopt
行将为您完成此操作。
我们遍历所有子目录中的所有*.tf
文件并打印出它们的目录名(通过切掉所有尾随的/*
组件)。 sort -u
用于删除重复项。