从 Bash 数组解析并重写 INI 文件

从 Bash 数组解析并重写 INI 文件

我有这些 bash 函数用于加载 INI 文件并将其解析为两个数组,一个用于键,第二个用于值,然后使用这些数组编写一个新的 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

我遇到的问题是有时我会得到一些空值

配置文件

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 文件中的空值?

答案1

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

您在这里依赖于分词,这确实会删除空字段,但如果您的任何值有空格,也会导致问题;它们将被分成多个字段。并且全局字符可以扩展为文件名。这里稍微讨论一下:为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?

此外,awk为每个输入行运行一个或两个实例的开销相当高。

幸运的是,shell 的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

相关内容