【问题标题】:Edit conf files and change values with sed or awk in the dockerfile?编辑 conf 文件并在 dockerfile 中使用 sed 或 awk 更改值?
【发布时间】:2018-06-23 12:58:56
【问题描述】:

我有一堆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 --set filename.conf server protocol https 的 crudini p.a 之类的工具,它实际上在服务器部分下添加了一个新条目,而不是取消对现有条目的注释。只要它工作正常。

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

我想要实现的是使用一个脚本/工具来修改这两种类型的文件。一个好的方法可能是:

  • 首先找到该部分,但忽略以;# 和部分名称开头的行
  • 在该部分的所有行中搜索参数。
    • 如果参数的行以;#开头,则替换整行(这样也去掉了空格,插入到相同的位置)
    • 如果没有找到该参数,则应添加该参数

我发现了很多脚本,其中包含很多代码,但需要一个使用 Docker conf 文件的小型解决方案。

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

【问题讨论】:

标签: linux awk sed dockerfile configuration-files


【解决方案1】:

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

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

#!/bin/bash

usage() {
    echo "Usage: $(basename $0) -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 $1 ]] && filename="$1";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($0, 2, index($0, "]") - 2))
}
$0 ~ ("^[[:space:]#;]*" item "[[:space:]]*=") {
    if (flag) {
        $0 = 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."

【讨论】:

  • 谢谢,很有帮助!
猜你喜欢
  • 1970-01-01
  • 2015-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
  • 2014-07-29
相关资源
最近更新 更多