我有一个循环数据库名称的脚本,如果当前数据库的名称在我的排除数组中,我想跳过它。我将如何在bash中实现这一目标?
excluded_databases=("template1" "template0")
for database in $databases
do
if ...; then
# perform something on the database...
fi
done
答案 0 :(得分:2)
您可以依次测试每个名称,但最好在一次操作中过滤列表。 (以下假设$databases
中没有名称包含空格,在for
循环中隐含空格。
for database in $(printf %s\\n $databases |
grep -Fvx "${excluded_databases[@]/#/-e}"); do
# something
done
习语的解释:
printf %s\\n ...
在一行上打印每个参数。
grep -Fvx
搜索整行(-F
)的完全匹配(-x
)并反转匹配结果(-v
)。
"${array[@]/#/-e}"
将-e
添加到数组array
的每个元素,这在您需要将数组的每个元素作为(重复的)命令行提供时非常有用实用程序的选项。在这种情况下,实用程序为grep
,-e
标志用于提供匹配模式。
我过去曾因printf %s\\n
而受到批评 - 有些人更喜欢printf '%s\n'
- 但我发现第一个更容易打字。 YMMV。
作为评论,似乎最好使$databases
成为数组以及$excluded_databases
,这将允许包含空格的名称。 printf | grep
解决方案仍然不允许名称中的换行符;解决这个问题很复杂。如果您要进行更改,则只需将printf
更改为printf %s\\n "${databases[@]}"
。
答案 1 :(得分:1)
您可以使用此条件检查数组中是否存在元素:
if [[ "${excluded_databases[@]/$database}" == "${excluded_databases[@]}" ]]
使用case
的另一个选项:
case "${excluded_databases[@]}" in *"$database"*) echo "found in array" ;; esac
答案 2 :(得分:1)
如果您使用的是bash 4或更高版本,那么使用关联数组会对您有帮助。
declare -A excluded_databases=(["template1"]=1 ["template0"]=1)
for database in $databases
do
if [ -z "${excluded_databases[$database]}" ]; then
continue
fi
# ... do something with $database
done