我正在按模式查询 mysql 数据库以获取数据库名称。目前我的实现如下所示:
include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES LIKE 'foo%'" \
| paste -sd ",")
这将返回与模式匹配的数据库名称的逗号分隔列表。
然而,我实际上只期望返回一个数据库名称,并且我认为当 mysql 返回 2 行结果时出错会更好。
有没有类似的东西:
include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES LIKE 'foo%'" \
| __error_if_two_lines__ )
答案1
您可以使用head
提取第一行:
include_databases=$(… | head -n 1)
然而,这将默默地忽略任何进一步的行。如果有更多行,您可以使用 awk 返回不同的退出代码:
include_databases=$(… | awk 'NR>1 {exit(2)} 1')
if [ $? -ne 0 ]; then
echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
fi
或者,在set -e
:
include_databases=$(… | awk 'NR>1 {print "mysql returned multiple lines! Aborting." >"/dev/stderr"; exit(2)} 1')
或者,您可以将输出存储在变量中,并测试它是否包含换行符。 (请注意,命令的最后一个换行符不包含在命令替换中。)
include_databases=$(…)
nl='
'
case $include_databases in
*"$nl"*) echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
esac
在 ksh/bash/zsh 中,但不是在普通 sh 中,您可以以更紧凑的方式编写此代码。
include_databases=$(…)
if [[ "$include_databases" = *$'\n'* ]]; then
echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
esac
答案2
我认为wc
是你的朋友。使用选项-l
来计算行数和-w
单词数。 (参见手册页)
mysql --batch --skip-column-names --execute "SHOW DATABASES" | wc -w
显示数据库的数量。
例如这样的东西
include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES")
numDB=$(echo $include_databases | wc -w)
[ $numDB -gt 1 ] && echo -n "$numDB dbs is more than "
echo "one db"
提示:您应该改进这个脚本,因为它使用了很多 subsheels