構成ファイルから分割変数にアクセスする

構成ファイルから分割変数にアクセスする

以下に説明するように、分割データを含む構成ファイルがあります。シェルスクリプトを使用して各変数にアクセスします。これを達成するためにsedコマンドを使用していますが、変数の設定を忘れた場合などの問題に直面しました。例: name [APP1] 名は [APP2] になります。
構成ファイル:

[APP1]
name=Application1
StatusScript=/home/status_APP1.sh
startScript=/home/start_APP1.sh
stopScript=/home/stop_APP1.sh
restartScript=/home/restart.APP1.sh

[APP2]
name=Application2
StatusScript=/home/status_APP2.sh
startScript=/home/start_APP2.sh
stopScript=/home/stop_APP2.sh
restartScript=/home/restart.APP2.sh
logdir=/log/APP2/
.
.
.
.
.
[APPN]
name=ApplicationN
StatusScript=/home/status_APPN.sh
startScript=/home/start_APPN.sh
stopScript=/home/stop_APPN.sh
restartScript=/home/restart.APPN.sh
logdir=/log/APPN

シェルコマンドの使用:

sed -nr "/^\[APP1\]/ { :l /^name[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}"

この問題を解決する方法はありますか?特定のセクションに特定の変数が設定されていない場合は、変数の値としてnullまたは0を渡します。

ベストアンサー1

設定を明確な形式に解析し、最新バージョンの連想配列として読みますbash

awk '/^\[/ { app=substr($0,2,length-2) } /=/ { print app "." $0 }' file.conf

次に、すべてのセクションヘッダーを探し、awk変数をappそのセクションヘッダーの内容に設定します。その後、各後続行の前に対応する値を追加し、その後にドットを追加します。

これにより、次のような出力が生成されます。

APP1.name=Application1
APP1.StatusScript=/home/status_APP1.sh
APP1.startScript=/home/start_APP1.sh
APP1.stopScript=/home/stop_APP1.sh
APP1.restartScript=/home/restart.APP1.sh
APP2.name=Application2
APP2.StatusScript=/home/status_APP2.sh
APP2.startScript=/home/start_APP2.sh
APP2.stopScript=/home/stop_APP2.sh
APP2.restartScript=/home/restart.APP2.sh
APP2.logdir=/log/APP2/

APP2セクションがない場合、その行nameAPP2.name表示されません。

次に連想配列として読みますbash

declare -A conf
while IFS='=' read -r key value; do
    conf[$key]="$value"
done < <(awk '/^\[/ { app=substr($0,2,length-2) } /=/ { print app "." $0 }' file.conf)

これでconf構成変数を照会できます。

printf 'The stopScript for APPN is "%s"\n' "${conf[APPN.stopScript]}"

が返されます

The stopScript for APPN is "/home/stop_APPN.sh"

存在しない値を照会すると、空の文字列が生成されます。


このawkコマンドは、次のsedコマンドに置き換えることもできます。

sed -n \
    -e '/^\[/{s/[][]//g;h;}' \
    -e '/=/{H;g;s/\n/./;p;s/\..*//;h;}' file.conf

展開してコメントする:

/^\[/{          # handle section headers
    s/[][]//g;  # remove [ and ]
    h;          # put into the hold-space
}

/=/{            # handle settings
    H;          # append the line to the hold-space with newline as delimiter
    g;          # get the hold-space
    s/\n/./;    # replace the newline with a dot
    p;          # output
    s/\..*//;   # remove everything after the dot
    h;          # put back into the hold-space
}

おすすめ記事