Bash配列からINIファイルを解析して再構築します。

Bash配列からINIファイルを解析して再構築します。

INIファイルをロードし、それをキー用と値用の2つの配列に解析するbash関数があります。次に、この配列を使用して新しいINIファイルを作成します。

declare -a ini_keys
declare -a ini_values

load_settings() {
    echo "Loading settings from \"$1\""
    ini_keys=()
    ini_values=()
    if [ -f "$1" ]; then
        ini_keys=($(awk -F ' *= *' '/^[a-z]/ {print $1}' "$1"))
        ini_values=($(awk -F ' *= *' '/^[a-z]/ {print $2}' "$1"))
        return 0
    fi
    echo "Missing \"$1\""
    return 1
}

save_settings() {
    echo "Saving settings to \"$1\""
    [ -f "$1" ] && mv "$1" "$1.bak"
    for index in "${!ini_keys[@]}"; do
        echo "${ini_keys[$index]}=${ini_values[$index]}" >> "$1"
    done
}

load_settings config.ini
save_settings new-config.ini

私が持っている問題は、時にはいくつかのNULL値が発生することです。

構成ファイル

key_01=value_01
key_02=value_02
key_03=
key_04=value_04
key_05=value_05

だから私は次のような "new-config.ini"で終わります。

key_01=value_01
key_02=value_02
key_03=value_04
key_04=value_05
key_05=

配列と新しく作成されたINIファイルでnull値を保持するには、この問題をどのように解決する必要がありますか?

ベストアンサー1

ini_values=($(awk -F ' *= *' '/^[a-z]/ {print $2}' "$1"))

ここでは、空のフィールドを削除する単語分割を使用していますが、値にスペースがある場合は複数のフィールドに分割され、問題が発生します。そして、グローバル文字をファイル名に拡張できます。ここで少し議論しましょう。スペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?

さらに、awk各入力行に対して1つまたは2つのインスタンスを実行するオーバーヘッドもかなり高くなります。

幸いなことに、シェルのread組み込み関数は入力を分割できるため、=次のことができます。連想配列は、キーと値の関係を直接表すことができるため、ここで使用されます。しかし、本当にしたい場合は、通常の配列を使用できます。

#!/bin/bash

configfile=config.ini
declare -A config

# read the ini file in
while IFS== read -r key val; do
    config+=(["$key"]="$val")
done < "$configfile"

# print and change one value
k=key_05
echo "key $k -> value ${config[$k]}"
config[$k]="foo bar"

# print it all out
for key in "${!config[@]}"; do
    printf "%s=%s\n" "$key" "${config[$key]}"
done

おすすめ記事