如何使用 bash 脚本通过使用 属性 文件作为输入将文件中的键替换为值

How to use bash script to replace keys with values in files by using a property file as the input

我有几个配置文件,其中包含可配置的数据。例子(看${ConnectorPort}):

<Connector port="${ConnectorPort}" protocol="HTTP/1.1" server="MyServer"
           connectionTimeout="20000"
           redirectPort="8443"
           URIEncoding="UTF-8"/>

在配置时,我想用给定属性文件中的值替换键。

问题是需要很长的时间(每个文件几秒钟)来遍历所有文件并遍历所有属性以检查每个 属性。下面的脚本。

知道如何使用 bash 更快地完成吗?

也许 sed 或 awk 中有一种方法可以将所有属性作为单个输入获取?

也许在内存中进行替换?

脚本:

for file in "${files[@]}"
do
    # echo ------
    #echo In file: $file
    #echo ------
    cp -f "$file" "$file.bak"
    unset replaced
    for prop in "${!props[@]}"
    do
        key="$prop"
        keyToReplace="${$prop}"
        val="${props[$key]}"
        # echo In prop: $key=$val
        sed -i "s|$keyToReplace|$val|Igw $file.change" "$file"
        assertReturnStatus $? "sed failed"
        if [ -z "$replaced" ] && [ -s "$file.change" ]; then
            replaced=true
            echo Replacing props in file "$file"
            cp -n "$file.bak" "$file.orig"
        fi
    done
    rm -f "$file.change"
    rm -f "$file.bak"
done

* 其中一项要求是在文件更改时创建备份 (.orig)。

谢谢。

循环内的循环导致每个文件多次 sed 到 运行。所以,去掉循环里面的循环。

declare -a sedArgs

for prop in "${!props[@]}"
do
    key="$prop"
    keyToReplace="${$prop}"
    val="${props[$key]}"
    # echo In prop: $key=$val
    #sed -i "s|$keyToReplace|$val|Igw $file.change" "$file"
    sedArgs+=("-e")
    sedArgs+=("s|$keyToReplace|$val|Ig")
done

for file in "${files[@]}"
do
    # echo ------
    #echo In file: "$file"
    #echo ------
    sed -i.orig "${sedArgs[@]}" $file
    cmp -s "$file" "${file}.orig" && mv "${file}.orig" "$file"

done

内存解决方案,将内容读取到内存并在内存中进行替换:

for file in "${files[@]}"
do
#   echo ------
#   echo In file: $file
#   echo ------
    unset replaced
    contentOrig=`cat "$file"`
    content="$contentOrig"
    for prop in "${!props[@]}"
    do
        # No need to search for all properties if there are
        if [[ ! "$content" == *'${'* ]]; then
            break
        fi
        key="$prop"
        keyToReplace="${$prop}"
        val="${props[$key]}"
#       echo In prop: $key=$val
        content="${content//$keyToReplace/$val}"
        assertReturnStatus $? "sed failed"
    done
    # TODO: Show warning if `${` still exists (Excluding `*.sh` files). We might have forgotten to add a property.
    if [[ "$content" != "$contentOrig" ]]; then
        let "filesReplacedCount++"
        cp -n "$file" "$file.orig"
        echo "$content" > "$file"
        echo Replaced props in file "$file"
    fi
done