shell a.sh 脚本读取了一个外部配置文件, 脚本内容如下:
#!/bin/bash
source /home/ec2-user/scripts/etc/test.d
echo ""| awk -v dict="$dict" '{for (i in dict) print i","dict[i]}'
配置文件内容如下:
$ cat etc/test.d
declare -A dict
dict=([1]="a" [2]="b")
执行后报错:
bash a.sh
awk: {for (i in dict) {print i","dict[i]}}
awk: ^ ?????????
所以想请教下如何才能将 shell 配置里的 关联数组 传到 awk 里面使用呢?
做不到, 我查阅了awk
和bash
的官方文档的大部分内容, 没有找到相关语法.
但从另一方面说, 你可能没意识到awk
和bash
是两种编程语言, 而在任意两种语言中, 复杂的数据结构都是不可能共享的. 你做不到将ruby
的数组变量共享到python
的程序, 除非某些人写一个中间沟通程序.
如何实现变量(对象)共享:
同种语言间的变量(或者对象)共享, 往往将对象序列化后存储到磁盘, 下次再从磁盘读取重新对象化来实现, 这能实现类型不变.
不同语言间的变量共享, 往往通过输入和输出来共享(
IO
), 你可以自定义输入输出格式, 也可以使用共享的格式, 如JSON
.两种方式原理没有本质区别, 只是第一种在底层做了同样的工作.
以数组为例, A
程序将数组一个个输出成字串, 并以:
分隔, 如a:b:c:d
, 再在B
程序读入, 调用split
分隔成数组. 以字典为例, 使用JSON
通用数据格式, 以{ 1: 'a', 2: 'b' }
输出, 再在另一个程序JSON.parse
构建对象.
不同语言间的变量共享的通用做法还是JSON
, 但awk
或bash
都不支持这个, 所以还是简单的IO
吧.
但遗憾的是, bash
没办法获取关联数组(也称字典或哈希或映射)的键, 而awk
也没有便捷的将字串转换成关联数组的内建函数.
唯一可行的方式:
source /etc/test.d
d=${dict[*]}
awk -v d=$d 'BEGIN {
split(d, d, ' ');
for (i in d) {
print d[i];
}
}'
类似上述代码, 虽然跟没写一样.
${d[*]}
意思是取索引数组的所有元素, 默认以
分隔, 你可以设置IFS
环境变量, 如:
, 以:
分隔. split
将字串以分隔符分隔写入数组变量.
问题
上述代码, 每一条在shell
中执行都没错, 但写到脚本里面就是运行不过去, 说找不到文件BEGIN...
. 我就日了狗了. 我把d="a b c"
就又能执行, 但写成d=${dict[*]}
就是执行不过去. 然后在交互式shell
里又查不出问题. fuck the bash
.
可以的话, 尽量选择现代脚本语言, 如python
, ruby
等, 在sh
历史的污垢里不知道隐藏了多少奇技淫巧, 恶心死我了, 最后的代码折腾了半小时, 主要的是我不是shell
新手.