bash連想配列をテキストファイルにラウンドトリップする方法


9

異なるスクリプト実行間の連想配列を記憶したいと思います。これまでのところ、1つのキーと値のペアを含むテキストファイルを指定しています。

(
[james]=bond
)

それを連想配列にロードして追加し、2番目のファイルにリダイレクトできるようにエコーするスクリプトです。

#!/bin/bash
file=`cat $1`
key=$2
value=$3
declare -A row="$file"
row[$key]=$value
echo "("
for server in "${!row[@]}"
    do echo "[$server]=${row[$server]}"; done
echo ")"

それから私はそれを次のように実行できます:

./arrays.sh file1 honey rider > file2 ; mv file2 file1

与える

(
[james]=bond
[honey]=rider
)

しかし、それは非常に不格好です。これを行うためのよりクリーンな方法はありますか?


4
declare -p hash > filehash連想配列を保存します。source file復元します。
ステファンChazelas

2
おそらくそれはarrays.bash...
mikeserv '10 / 06/14

回答:


10

ではbashdeclare -p変数の定義をシェルコードとして解釈できるようにダンプするために使用できるため、次のコマンドでファイルを更新できます。

#! /bin/bash -
file=${1?}; shift
declare -A row
source -- "$file" || exit
while [ "$#" -ge 2 ]; do
  row[$1]=$2
  shift 2
done
declare -p row > "$file"

ファイルは同じロケール(少なくとも同じLC_CTYPEカテゴリ)で生成およびソースされることが重要です。

ファイルの内容を表示するスクリプトは次のようになります。

#! /bin/bash -
file=${1?}; shift
declare -A row
source -- "$file"
for i in "${!row[@]}"
do
  printf 'key  : %s\n' "$i"
  printf 'value: %s\n' "${row[$i]}"
done

自己認定パラメータを取得しました!しかし、より具体的なエラー文字列はそれほど有用ではないでしょうか?
mikeserv 2014年

@mikeserv、確かに、それは答えのポイントを超えています。必ず、必要に応じて適切な構文チェックを追加してください。また、ファイル名の後に偶数の引数があることを確認することもできます(または、単一の要素を削除する手段として奇数の単一の引数を使用します)。
ステファンChazelas

わからない…多分私に編集を頼まないで...吸血鬼を招待することになっているわけじゃないんだけど…やったことは終わったと思う。
mikeserv 2014年

あ、ごめんなさい。文字通りそれを取るべきではなかったと思いますか?私はあなたが尋ねたようにして、それを複雑にすることなくもう少し堅牢にしました。
mikeserv 2014年

2
@ ec2011、の最新バージョンbash(回答が書かれた時点で利用可能であったものよりも新しい)では、readarray -td '' arrayNUL区切りのレコードを通常の配列に読み取り、それを連想配列に変換することができます。
ステファンChazelas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.