0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Bash で dotnev ファイルを読み込んで複雑な環境変数を sed でパースする

Posted at

あるプロジェクトで、環境変数が.envファイルに格納されており、その中の一つの環境変数が、独特のフォーマットで記述されており、それをパースする必要があった。
そのメモとしてブログを残しておく。

問題

.env ファイルに格納された文字列がある。

FOO=BAR
SOME='{ aks_node_vm_size="Standard_L8s_v2", dns_prefix="staging-e", agent_count_min=1,agent_count_max=10, agent_count_enable_autoscale=true, kubernetes_version="1.14.7", cluster_name="some-aks", vnet_subnet_name="some-aks-subnet", gateway_name="some-gateway" }'

この状況で、cluster_name の値だけを取得したい。

dotnenv ファイルを読み込んで環境変数にする

これは意外とややこしい。当初はgrepを使ってやろうとしていたが、上記のような複雑な変数は上手く読めなかったりした。しかし簡単な方法があった。

set -o allexport; 
source $TEST_ENV_FILE_PATH
set +o allexport; 

ちなみに-o allexport は全ての変数をexportする指定で、-a でもよいようです。

ちなみに +o の指定はオプションの無効化になります。つまり、AllExportを指定した状態でEnvファイルを読み込めばまずは、環境変数までもってこれます。

複雑な環境変数をパースする。

SOME='{ aks_node_vm_size="Standard_L8s_v2", dns_prefix="staging-engine", agent_count_min=1,agent_count_max=10, agent_count_enable_autoscale=true, kubernetes_version="1.14.7", cluster_name="some-aks", vnet_subnet_name="some-aks-subnet", gateway_name="some-gateway" }'

これのパースだが、最初はこんなコードを書いていた。できるねんけど、ダサさが漂っている。基本的にやってることは、IFSを変えて,で分割して、
余計なダブルクオートや、変数名をカットという感じ。

#!/bin/bash

OLDIFS=$IFS
IFS=","
pattern="^cluster_name="
CLUSTER_NAME=""
for kv in $SOME
KEY_VALUE=$(echo $kv | xargs)
if [[ $KEY_VALUE =~ $pattern ]]; then
   CLUSTER_NAME=$(echo $KEY_VALUE | sed 's/cluster_name=//')
fi
done

echo $CLUSTER_NAME

これを何とかワンライナーで出来ないかと思い、Sedを調査した。Sedの置換のコマンドを使っている。
cluster_name=の直後で、空白、もしくは,ではない文字列をヒットさせる。 \( \) は、ここで
ヒットした内容を後で参照できる。つまり、空白や,が先ほどの文字列の区切りにでてくるので、次にそれがヒットするまでは
( )の中の内容になる。.*は任意の文字列にヒットする。この内容(つまり、cluster_name=以降の文字列)を、\1 つまり、
( ) の中でヒットした内容を置換する。つまりそれは、"some-aks" になるので、それのダブルクオートをxargsでとって終わり。

CLUSTER_NAME=$(echo $SOME | sed 's/.*cluster_name=\([^ ,]*\).*/\1/' | xargs)
echo $CLUSTER_NAME

xargs で、"" が取り除かれるのは、元々 xargsはデリミタで分割した文字を返すもの

xargsは、改行等で区切られた標準入力を読み込み、空白で区切られた1行の文字列へ加工し、それを引数として指定したコマンドへ渡して実行させる。

なので、デリミタが無い場合は、単純に、1行の文字列に加工するけど、""をストリップするのだろう。

部分抽出に関しては下記のブログを参考にしました。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?