我有以下脚本从 mysql 检索信息
#!/bin/bash
set -f
IFS=$'\n'
arr=($(sudo mysql -u root -h localhost -e "USE mydb;SELECT * FROM users"))
for i in "${arr[@]}"
do
echo "$i}"
done
当我运行之前的脚本时,我得到:
id firstname lastname phonenumber password email ip}
5 User User 111111111111 Passtest1 [email protected] 147.236.147.91}
这是问题所在:我想在运行时打印一个键值:
#!/bin/bash
set -f
IFS=$'\n'
arr=($(sudo mysql -u root -h localhost -e "USE mydb;SELECT * FROM users"))
echo ${arr[ip]}
然后我得到:
id firstname lastname phonenumber password email ip
如何打印 id 值(在本例中为 )5
?
答案1
第一的,我可以建议您通过以下方式运行所有 shell 脚本吗外壳检查- 也可在许多 Linux 发行版上作为独立程序使用 - 检测语法错误。例如echo $i}
看起来像是一个拼写错误,它只能“起作用”,因为$i
与 相同${i}
,并且附加的“仅”会导致附加到预期输出的}
杂散。}
第二,这里似乎对数组和变量的使用存在误解。您想要打印ip
输出的“实际数据行”标记的最后一列。您的使用
echo ${arr[ip]}
但是不起作用,因为您既没有声明(如declare -A arr
)也没有“填充”arr
为联想性的数组,这意味着像这样取消引用数组是行不通的 - shell 会期望这里有一个数字数组索引。如果您提供一个文本字符串(如ip
),则行为将取决于 shell,尽管它可能会将其解释为变量名,发现该变量未定义(即求值为空字符串),然后仅打印数组的第一个条目(您的情况的第一行)。
另外,即使将数组声明为关联数组,“列标题”与“数组索引”的匹配也不会自动进行;如果您希望按照您所描述的方式进行有针对性的访问,则必须手动执行此操作。
第三,大多数情况下文本处理是使用文本处理工具可以更好地执行,例如awk
而不是在 shell 中进行。由于您想忽略标题行并打印第二行的最后一列,我建议
sudo mysql -u root -h localhost -e "USE mydb;SELECT * FROM users" | awk 'NR==2{print $7}'
它将处理通过程序sudo
调用命令的调用的输出,该程序仅处理第二行(条件)并在遇到该行时打印第七列。mysql
awk
NR==2
第四,最好的选择仍然是使用数据库工具本身来选择数据。我不是 SQL 专家,但我认为诸如这样的查询
mysql -u root -h localhost -e "USE mydb; SELECT ip FROM users WHERE id='5'"
应该可以工作(但请在生产使用之前使用非关键示例进行验证)。