bash - 以编程方式为查找命令(Bash)构建目录排除列表
问题描述
我有一组目录要从我的 find 命令的结果中排除,例如EXCLUDE=("foo" "bar")
.
我可以像这样从交互式终端运行它:
find . -name 'hvr.yml' -not -path "foo/*" -not -path "bar/*"
所以我试图建立这样的论点:
getServersToCheck() {
# Build command arguments to exclude given dirs
local exclude_command="-not -path"
local excount=${#EXCLUDE[@]}
for ((i=0;i<excount;i++)); do
EXCLUDE[i]="${exclude_command} ${EXCLUDE[i]}/*"
done
find . -name 'hvr.yml' "${EXCLUDE[@]}"
}
但这会导致 find 抛出未知谓词错误:'-not -path foo/*'
有没有办法做到这一点?当我回显命令时,它看起来是正确的,但必须有一些 bash 语法规则导致它无法按我的预期工作。
更新:
\"
当我读到只有带引号的字符串才会发生通配时,我在排除路径周围添加了内容。xtrace 显示以下内容:
find . -name hvr.yml -not -path '"foo/*"' -not -path '"bar/*"'
单引号可能是问题
删除\"
并运行 xtrace 表明在 for 循环中应用了通配符,导致:
find . -name hvr.yml -not -path "foo/fileinfoo" "foo/somethingelseinfoo" -not -path "bar/*" "bar/fileinbar" "bar/otherfilesinbar"
所以 find 抱怨随机路径被作为参数给出。
有没有办法扩展 EXCLUDE 数组并将 /* 添加到命令中每个元素的末尾?
解决方案
通过使用 grep 找到了我试图实现的替代解决方案:
EXCLUDE=("abc" "def")
getPaths() {
local exclude_count=${#EXCLUDE[@]}
if [ $exclude_count -eq 0 ]; then
find . -name $FILENAME | tr '\n' ' '
return $?
fi
# Concat excluded servers as grep regex
local regex="(${EXCLUDE[0]}"
for ((i=1;i<exclude_count;i++)); do
regex="${regex}|${EXCLUDE[i]}"
done
regex="${regex})"
find . -name $FILENAME | grep -Ev "${regex}" | tr '\n' ' '
return $?
}
- 如果 exclude 为空,则运行正常的 find 命令。
- 否则,它会为 grep 构建一个正则表达式,以过滤掉这个示例中最终看起来像 (abc|def) 的内容。
推荐阅读
- android - 如何在 Flutter 中拍摄相机预览截图
- python - 无法使用 find_element_by_link_text() 抓取元素
- android - 水平排列在 Jetpack Compose Row 中不起作用
- python - 将第一个项目与第二个列表中的所有项目进行比较
- java - 如果 List 内的属性有多个对象,则在迭代时创建多个对象
- c# - 使用 Moq 和 AutoMock 模拟被测类的方法
- ruby - 在Ruby中将数学表达式转换为字符串
- docker - 弹性搜索启动但无法访问
- r - 来自 R 中的箭头包的 read_csv_arrow 中的时间戳解析问题
- python - 无法计算 django 中的 PostgeSQL 请求