记一次eval的神奇用法,字符串重解析为map
一、场景需求
在shell脚本结合sqlplus使用时,偶尔会遇到sqlplus中执行的select查询语句返回结果需要数组,或者map的方式来存储,但是当接收到拼接的字符串返回结果后,又遇到shell无法像java一样实现灵活的解析。但我在网络上查询资料,千篇一律只是最简单的shell中的map用法,至于如何解析存入map变量缺只字未提。最终发现eval对这方面解析有神奇功效,特此记一笔,防遗忘。
二、代码情景
#!/bin/bash
declare -A tabMap;
sqlstr=`sqlplus -s $dbusr/$dbpwd@$dbname << EOF
set pagesize 0 feedback off verify off heading off echo off
set serveroutput on
set line 4000
col TAB format a4000
select '["'||tab_nm||'"]="'||file_nm||'"' as TAB from ares_etl_conf;
/
quit
EOF
`
echo $sqlstr
命令中关于set line 4000和 col TAB format a4000的解释:
在查询字段中,有部分字段值过长是,在生成字符串拼接结果时,会出现换行情况,最终输出字符会无故多出很多不必要的空格,所以需要手动指定输出字符的格式长度,这里我行和列自适应都设置了4000
这样的查询可以得到一个类似于初始化map的赋值格式,但是得到的 $sqlstr
却是字符串类型,所以需要转换为map还需要特殊解析,$sqlstr
内容如下:
["a1"]="1" ["a2"]="2" ["a3"]="3" # 每个["key"]="value"之间用空格隔开
三、最终解析代码
#!/bin/bash
eval "declare -A tabMap=(`sqlplus -s $dbusr/$dbpwd@$dbname << EOF
set pagesize 0 feedback off verify off heading off echo off
set serveroutput on
set line 4000
col TAB format a4000
select '["'||tab_nm||'"]="'||file_nm||'"' from ares_etl_conf;
/
quit
EOF
`)"
echo ${!tabMap[@]}
最终是不是很简单呢,欢迎大家指点,是否还有其他更简单的办法。
四、eval命令参考
功能说明:重新运算求出参数的内容。
语 法:eval [参数]
补充说明:eval可读取一连串的参数,然后再依参数本身的特性来执行。
参 数:参数不限数目,彼此之间用分号分开。
1.eval命令将会首先扫描命令行进行所有的替换,憨厚再执行命令。该命令使用于那些一次扫描无法实>现其功能的变量。该命令对变量进行两次扫描。这些需要进行两次扫描的变量有时候被称为复杂变量。
2.eval也可以用于回显简单变量,不一定时复杂变量。
NAME=ZONE
eval echo $NAME等价于echo $NAME
3.两次扫描
test.txt内容:hello shell world!
myfile=“cat test.txt”
(1)echo $myfile #result:cat test.txt
(2)eval echo $myfile #result:hello shell world!
从(2)可以知道第一次扫描进行了变量替换,第二次扫描执行了该字符串中所包含的命令
4.获得最后一个参数
echo “Last argument is $(eval echo $$#)”
echo “Last argument is $(eval echo $#)”