在 dockerfile 中使用 sed 或 awk 编辑 conf 文件并更改值?

Edit conf files and change values with sed or awk in the dockerfile?

我有一堆conf文件,可以描述为两种类型:

类型 1(典型的类似 conf 文件的 ini 文件):

[server]
# Protocol (http, https)
;protocol = http

# The ip address to bind to, empty will bind to all interfaces
;http_addr = 192.168.33.2

# The http port  to use
;http_port = 3000    

类型 2(格式错误的 conf 文件):

###
### [http]
###

[http]
# Determines whether HTTP endpoint is enabled.
# enabled = true

# The bind address used by the HTTP service.
# bind-address = ":8080"

对于 Type1 conf 文件,我可以成功地使用像 crudini p.a 和 crudini --set filename.conf server protocol https 这样的工具,它实际上在服务器部分下添加了一个新条目,而不是取消对现有条目的注释。只要它能正常工作。

crudini 对类型 2 文件失败并出现解析错误,因为 conf 文件不是正确的 ini 文件。对于这些,我尝试使用 sed 但失败了。

我想要实现的是使用一个 script/tool 来修改两种类型的文件。也许一个好的方法是:

我找到了很多脚本,其中有很多代码,但需要一个使用 Docker 配置文件的小型解决方案。

你能帮我找到一个优雅的解决方案吗?

这里。向前支付。腿部工作由 gawk 处理。我用 --posix 开关对其进行了测试,因此我认为它也应该适用于 mawk 和其他 awk 变体。

脚本将引用包含空格和等号的值,以及引用被替换值的值。我不熟悉 Docker 文件,但由于在您的第二个示例中引用了“:8000”,我认为引用可能很重要。

#!/bin/bash

usage() {
    echo "Usage: $(basename [=10=]) -s section -i item -v value filename"
    exit
}

export LC_ALL=C

while getopts "s:i:v:" i || (( $# )); do {
    case $i in
        s) section="$OPTARG";;
        i) item="$OPTARG";;
        v) value="$OPTARG";;
        ?) [[ -f  ]] && filename="";shift;;
    esac
}; done

[[ -z "$section" ]] || [[ -z "$item" ]] || [[ -z "$filename" ]] && usage

[[ -w "$filename" ]] && {
    tmpfile="$(mktemp -p /dev/shm)"
    [[ $(whoami) = "root" ]] && chown --reference="$filename" "$tmpfile"
    chmod --reference="$filename" "$tmpfile"
} || {
    echo "Invalid filename: $filename"
    usage
}

cleanup() {
    [[ -f "$tmpfile" ]] && rm -f "$tmpfile"
    exit
}
trap cleanup EXIT

awk -v section="$section" -v item="$item" -v value="$value" '
function quote(str) { return "\"" str "\"" }
/^\[[^\]]+\]/ {
    if (flag) {
        printf "%s = %s\n", item, value ~ /[[:space:]=]/ ? quote(value) : value
        flag = 0
    }
    else flag = (section == substr([=10=], 2, index([=10=], "]") - 2))
}
[=10=] ~ ("^[[:space:]#;]*" item "[[:space:]]*=") {
    if (flag) {
        [=10=] = sprintf("%s = %s", item, /"/ || value ~ /[[:space:]=]/ ? quote(value) : value)
        flag = 0
    }
}
1
END { if (flag) printf "%s = %s", item, value ~ /[[:space:]=]/ ? quote(value) : value }
' "$filename" >"$tmpfile"

[[ -s "$tmpfile" ]] && mv "$tmpfile" "$filename" || echo "Something went horribly wrong."