我想將一個 yaml 檔案的內容讀入 bash 關聯陣列,這是一個簡單的鍵值映射。
例子map.yaml
---
a: "2"
b: "3"
api_key: "somekey:thatcancontainany@chara$$ter"
鍵可以包含除空格以外
的任何字符 值可以包含不受限制的任何字符 $!:=@etc
始終不變的是鍵和值之間的分隔符是:
劇本proceses.sh
#!/usr/bin/env bash
declare -A map
# how to read here into map variable, from map.yml file
#map=populatesomehowfrommap.yaml
for key in "${!map[@]}"
do
echo "key : $key"
echo "value: ${map[$key]}"
done
我嘗試使用yq tool,類似于 json tool jq 但還沒有成功。
uj5u.com熱心網友回復:
具有以下限制:
key: "value"單行的簡單 YAML- 鍵不能包含
: - 值總是被包裹在
"
#!/usr/bin/env bash
declare -A map
regex='^([^:] ):[[:space:]] "(.*)"[[:space:]]*$'
while IFS='' read -r line
do
if [[ $line =~ $regex ]]
then
printf -v map["${BASH_REMATCH[1]}"] '%b' "${BASH_REMATCH[2]}"
else
echo "skipping: $line" 1>&2
fi
done < map.yaml
更新
這是一個使用 的強大解決方案,如果內置過濾器實作無損 TSV 轉義規則而不是 CSV 規則yq,這將更簡單。@tsv
#!/usr/bin/env bash
declare -A map
while IFS=$'\t' read key value
do
printf -v map["$key"] '%b' "$value"
done < <(
yq e '
to_entries | .[] |
[
(.key | sub("\\","\\") | sub("\n","\n") | sub("\r","\r") | sub("\t","\t")),
(.value | sub("\\","\\") | sub("\n","\n") | sub("\r","\r") | sub("\t","\t"))
] |
join(" ")
' map.yaml
)
注意:需要join文字Tab
uj5u.com熱心網友回復:
一種方法是讓yq在一行上輸出每個鍵/值對,語法如下:
key@value
然后我們可以使用bash 的 IFS來拆分這些值。
這@只是一個示例,可以用任何單個字符替換
這可行,但請注意以下限制:
- 它不需要嵌套值,只有一個平面串列`
@YAML 鍵/值中不存在欄位分隔符(在示例中)
#!/bin/bash
declare -A arr
while IFS="@" read -r key value
do
arr[$key]="$value"
done < <(yq e 'to_entries | .[] | (.key "@" .value)' input.yaml)
for key in "${!arr[@]}"
do
echo "key : $key"
echo "value: ${arr[$key]}"
done
$ cat input.yaml
---
a: "bar"
b: "foo"
$
$
$ ./script.sh
key : a
value: bar
key : b
value: foo
$
uj5u.com熱心網友回復:
我使用了@Fravadona 的答案,所以將其標記為答案
在對我的用例進行一些修改之后,對我有用的看起來像:
DEFS_PATH="definitions"
declare -A ssmMap
for file in ${DEFS_PATH}/*
do
filename=$(basename -- "$file")
projectName="${filename%.*}"
regex='^([^:] ):[[:space:]]*"(.*)"[[:space:]]*$'
while IFS='' read -r line
do
if [[ $line =~ $regex ]]
then
value="${BASH_REMATCH[2]}"
value=${value//"{{ ssm_env }}"/$INFRA_ENV}
value=${value//"{{ ssm_reg }}"/$SSM_REGION}
value=${value//"{{ projectName }}"/$projectName}
printf -v ssmMap["${BASH_REMATCH[1]}"] '%b' "$value"
else
echo "skipping: $line" 1>&2
fi
done < "$file"
done
基本上在實際用例中,我有一個 yaml 定義所在的檔案夾。我遍歷所有這些以形成關聯陣列 ssmMap
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/465463.html
