![解析 YAML 以在 shell 中创建动态查询](https://linux22.com/image/197652/%E8%A7%A3%E6%9E%90%20YAML%20%E4%BB%A5%E5%9C%A8%20shell%20%E4%B8%AD%E5%88%9B%E5%BB%BA%E5%8A%A8%E6%80%81%E6%9F%A5%E8%AF%A2.png)
我对脚本编写非常陌生,我的任务是找出一种编写 shell 脚本的方法,该脚本将根据提供的 YAML 文档创建 SQL 查询。我可以追踪到yq
要使用的解析器;但是,我一直不知道如何使用 YAML 子节点中的各个值。我需要解析的示例 YAML 是:
config:
- system1:
database_name: database1
port: '1234'
table:
- name: table1
values: 'table_id, value1, 30, randomValue'
- name: table2
values: 'table_id, value1, randomValue, randomValue, value2'
- name: table2
values: 'table_id, value2, randomValue, randomValue'
- system2:
database_name: database2
port: '12345'
table:
- name: table4
values: 'table_id, value3, 30, randomValue'
- name: table5
values: 'table_id, randomValue, randomValue, value4'
- name: table6
values: 'table_id, value3, value4'
我当前尝试编写的脚本只不过是SELECT
语句,但稍后会演变:
# This will later be used to create insert/update queries based on the values so
# will be needing a handle for that too.
psql -h localhost -p $PORT -d $DATABASE << EOF
select * from $TABLE LIMIT 10;
EOF
如果可能的话,在听起来没有必要的情况下,我希望看到有关如何使用yq
库的建议,因为它支持在 SQL 部分完成后我需要对此脚本执行的一系列操作。
如果问题太愚蠢,我深表歉意,这将是我第一次接触 shell 脚本。
如果相关的话,我正在使用 Ubuntu 18.4 发行版。
答案1
使用安德烈·基斯柳克yq
(围绕 JSON 处理器的 YAML 感知包装器jq
)而不是 Mike Farah 的yq
,您可以创建执行查询所需的 shell 语句,如下所示:
yq -r '
.config[] |
map(
@sh "psql -h localhost -p \(.port) -d \(.database_name) <<END_SQL",
(.table | map("SELECT \(.values) FROM \(.name) LIMIT 10;"))[],
"END_SQL"
)[]' file
或者,如果您不喜欢使用map
:
yq -r '
.config[][] |
@sh "psql -h localhost -p \(.port) -d \(.database_name) <<END_SQL",
(.table[] | "SELECT \(.values) FROM \(.name) LIMIT 10;"),
"END_SQL"' file
这会迭代数组config
,psql
为每个元素创建一个命令。该psql
命令从条目的和值(使用输出运算符为 shell 引用)获取其-p
和选项参数。-d
port
database_name
@sh
实际的 SQL 语句通过此处文档重定向提供给命令,并由任意选择的字符串分隔END_SQL
。这些语句values
按原样使用需要提取的字段的值,并将该name
值用作从中提取字段的表的名称。不对这些值执行特殊引用。
根据问题中的数据,上述命令生成以下 shell 代码:
psql -h localhost -p '1234' -d 'database1' <<END_SQL
SELECT table_id, value1, 30, randomValue FROM table1 LIMIT 10;
SELECT table_id, value1, randomValue, randomValue, value2 FROM table2 LIMIT 10;
SELECT table_id, value2, randomValue, randomValue FROM table2 LIMIT 10;
END_SQL
psql -h localhost -p '12345' -d 'database2' <<END_SQL
SELECT table_id, value3, 30, randomValue FROM table4 LIMIT 10;
SELECT table_id, randomValue, randomValue, value4 FROM table5 LIMIT 10;
SELECT table_id, value3, value4 FROM table6 LIMIT 10;
END_SQL
然后,您可以通过管道将其传递到sh -s
或使用 对其求值来执行此代码eval
。