我有一个目录列表。其中一些人的名字中带有图案。我为这些模式制作了一个数组。
然后我应该循环结果find
,并将每个结果与每个模式进行比较,如果匹配则跳过该项目。
这是我的代码:
declare -a patterns=("*Api" "*Panel" "Common" "Site*" ".*")
while read folder; do
if [[ $folder == "" ]]; then continue; fi
for pattern in "${patterns[@]}"
do
echo "Checking $folder $pattern ..."
if [[ $folder == $pattern ]]; then
echo "Matched $folder $pattern"
fi
done
done <<< "$({ find /some-path -mindepth 1 -maxdepth 1 -type d | cut -d'/' -f3 | sort })"
但这不起作用。例如,AdminApi
作为目录应该匹配*Api
.
如果我静态地做,就像if [[ AdminApi == *Api ]]; then echo 'yes'; fi
它起作用一样。
但是当我将其作为数组循环时,它不起作用。
这里有什么问题?
答案1
使用zsh
代替bash
会使这变得更容易(并且可靠):
typeset -A patterns=(
'*Api' .
'*Panel' .
'Common' .
'Site*' .
'.*' .
)
for dir in /some/path/*(ND/:t); do
matched_patterns=( ${(k)patterns[(K)$dir]} )
if (( $#matched_patterns )) print -r -- $dir matched ${(j[, ])matched_patterns}
done
例如给出:
.Panel matched .*, *Panel
SiteApi matched Site*, *Api
这使用了K
下标标志对于关联数组,这会导致扩展返回键作为模式与下标匹配的元素。并与k
参数扩展标志,它是键,而不是返回的值。您可以删除它并将关联数组定义为:
typeset -A patterns=(
'*Api' 'API pattern'
'*Panel' 'panel pattern'
Common Common
'Site*' 'site pattern'
'.*' 'hidden file'
)
要得到:
.Panel matched hidden file, panel pattern
SiteApi matched site pattern, API pattern
例如。
如果目的只是获取与这些模式匹配的目录列表,那么,它只是:
patterns=( '*Api' '*Panel' Common 'Site*' '.*' )
dirnames=( /some/path/(${(j[|])~patterns})(ND/:t) )
print -rC1 -- $dirnames
或者对于那些不匹配的:
set -o extendedglob
patterns=( '*Api' '*Panel' Common 'Site*' '.*' )
dirnames=( /some/path/^(${(j[|])~patterns})(ND/:t) )
print -rC1 -- $dirnames
至于您的方法,您可能需要阅读:
- 理解“IFS=读取-r行”(虽然在这里你需要
IFS= read -rd '' file
你无法使用的<<<
,请参阅下一个问题:) - 为什么循环查找的输出是不好的做法?
- 为什么 printf 比 echo 更好?
尽管这些都不能解释为什么它对你不起作用。
它对我有用,我看到:
Checking .Panel *Api ...
Checking .Panel *Panel ...
Matched .Panel *Panel
Checking .Panel Common ...
Checking .Panel Site*, ...
Checking .Panel .* ...
Matched .Panel .*
Checking SiteApi *Api ...
Matched SiteApi *Api
Checking SiteApi *Panel ...
Checking SiteApi Common ...
Checking SiteApi Site* ...
Matched SiteApi Site*
Checking SiteApi .* ...
bash -o xtrace
您可能需要使用(与 相同)运行脚本来bash -x
查看发生了什么。
或者:
BASH_XTRACEFD=7 7> file.log bash -o xtrace ./the-script
将跟踪输出保存在文件中。
或者在选定的位置添加一些set -o xtrace
(+o
以禁用)以启用/禁用该跟踪。