以编程方式为查找命令构建目录排除列表 (Bash)
Build Directory Exclusion List Programmatically for Find Command (Bash)
我有一组目录要从我的查找命令的结果中排除,类似于 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 语法规则导致它无法按我预期的方式工作。
更新:
我在要排除的路径周围添加了 \"
,因为我读到 globbing 只发生在带引号的字符串中。 xtrace 显示以下内容:
find . -name hvr.yml -not -path '"foo/*"' -not -path '"bar/*"'
单引号可能是问题所在
删除 \"
和 运行 xtrace 表明在 for 循环中应用了 globbing,导致:
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 为空,则运行正常的查找命令。
- 否则,它会为 grep 构建一个正则表达式以过滤掉最终看起来像 (abc|def) 的示例。
我有一组目录要从我的查找命令的结果中排除,类似于 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 语法规则导致它无法按我预期的方式工作。
更新:
我在要排除的路径周围添加了 \"
,因为我读到 globbing 只发生在带引号的字符串中。 xtrace 显示以下内容:
find . -name hvr.yml -not -path '"foo/*"' -not -path '"bar/*"'
单引号可能是问题所在
删除 \"
和 运行 xtrace 表明在 for 循环中应用了 globbing,导致:
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 为空,则运行正常的查找命令。
- 否则,它会为 grep 构建一个正则表达式以过滤掉最终看起来像 (abc|def) 的示例。