file
以下があるとしましょう。
var1='a random text'
var2='another random text'
var3='a third random text'
eval
このようなコマンドを使用すると、これらの変数はすべてシェルに直接保存されることがわかります。
$ eval $(cat file)
これにより、私のシェルは$var1
、$var2
および$var3
その内容を生成します。これを知っている場合は、次のようにJSONを手動で作成できます。
$ JSON="{ \"var1\" : \"$var1\", \"var2\" : \"$var2\", \"var3\" : \"$var3\"}"
これにより、有効なJSONが生成されます。
$ echo $JSON
{ "var1" : "a random text", "var2" : "another random text", "var3" : "a third random text"}
ここで問題は、var1、var2、およびvar3キーをハードコーディングしたことです。私の場合、ファイルはより大きく、より多くの変数を保存できます(var1、var2、およびvar3だけでなく)。私はシェルにファイル変数を保存するのと同じように、コマンドラインを使用してこれを行う簡単な方法があるかどうか疑問に思いましたが、eval
変数を保存する代わりにJSON出力を生成しました。可能ですか?コマンドラインを使用して、同様の構造のファイルをJSONに直接変換できますか?
私の代替ソリューションは、そのファイルで文字ごとに実行されるコード(シェルを使用せずに)を開発し、ループからすべてを動的に分離することです。しかし、私がこの質問をするのは、解決策を過度に複雑にするのを避けたいからです。
答え1
組み合わせの使用jo
(ここ)とjq
(からここ)シェル変数を生成しないか、シェルがファイルをまったく解釈しないようにします。
jo <file |
jq --arg sq "'" '.[] |= ( ltrimstr($sq) | rtrimstr($sq) )'
これはjo
JSONドキュメントを生成するために初めて使用されます。
{
"var1": "'a random text'",
"var2": "'another random text'",
"var3": "'a third random text'"
}
(しかし一行に)。これは、ファイルの変数割り当てをキーと値のペアとして解釈することによって行われます。
次に、このjq
ツールを使用して、各値の先頭と末尾の単一引用符を削除します。
最終結果は
{
"var1": "a random text",
"var2": "another random text",
"var3": "a third random text"
}
これは値に含まれる改行文字に対処できません。ただし、他の特殊文字は.jsonによって自動的にエンコードされますjo
。
答え2
を使用し、zsh
ファイル構文がの構文と互換性があり、ファイルがシェル拡張子zsh
(たとえばvar1=~/foo
、、、、var2=$var1
... var3=$(uname)
)を使用せず、値がUTF-8でエンコードされたテキストであると仮定すると、次のようになります。 :
tokens=( ${(Q)${(zZ[nC])"$(<file)"}} )
シェル構文に従ってファイルの内容を表示し(z
パラメータ拡張フラグを使用して引用符のない改行を空白として処理し、シェルコメントを削除するようにZ[flags]
調整(使用))、パラメータ拡張フラグを使用して引用符の1つのレイヤーを削除するします。n
C
Q
"
その後、これらのトークンをjsonをエンコードできる項目(改行、バックスラッシュ、文字などを含む制御文字の処理)に渡すことができます。
perl -CA -MJSON -le '
for (@ARGV) {
if (/(.*?)=(.*)/s) {
$h{$1} = $2;
}
}
print encode_json \%h' -- $tokens
file
たとえば、次のメッセージがあります。
var1='a random text' # comment
var2='another'\'' random text'
var3='a third random text'
name=$'St\u00e9phane Chazelas'
empty=
at=@
more=broken\
down"with 1 \\ backslash"
numstring=1.1
それは以下を提供します:
{"numstring":"1.1","name":"Stéphane Chazelas","empty":"","more":"brokendownwith 1 \\ backslash","var1":"a random text","at":"@","var2":"another' random text","var3":"a third random text"}