Score:0

sed: customizing config file header with a defined length?

us flag

I use sed to customize LXC container configuration files from the LXC host. That works well so far. When adjusting comment headers (hostname and date), there are aesthetic problems with the width of the headers, since when the hostname with different lengths are replaced, the total width of the heather is not automatically compensated for at the end.

in my example the string SERVER should be replaced.

############################
# RSYSLOG Konfiguration    #
# SERVER:/etc/rsyslog.conf #
# t12@RMS 2020-03-23       #
############################
############################
# RSYSLOG Konfiguration    #
# gersrv:/etc/rsyslog.conf   #
# t12@RMS 2020-04-23       #
############################
############################
# RSYSLOG Konfiguration    #
# sv4:/etc/rsyslog.conf   #
# t12@RMS 2020-06-23       #
############################

How can I get this with sed? Or do I need awk?

sed -i "s/SERVER/${servername}/g" /path to container/etc/rsyslog.conf
Score:1
in flag

Here you are a solution:

I use the length of the first dashes line as a length reference.

#! /bin/bash

RSYSLOG_FILENAME="/etc/rsyslog.conf"

awk -v servername="$1" '
/^#+$/ {
    ndash = length($0)
    print
    next
}
/^# SERVER:/ {
    str = "# " servername ":/etc/rsyslog.conf"
    nspace = ndash - length(str) - 1
    if (nspace < 1) { nspace = 1 }
    printf("%s%*.*s#\n", str, nspace, nspace, "")
    next
}
{
    print
}
' "${RSYSLOG_FILENAME}" > "${RSYSLOG_FILENAME}.tmp"

mv "${RSYSLOG_FILENAME}.tmp" "${RSYSLOG_FILENAME}"

UPDATE

For multiple files.

File: ./sysconf.sh

#! /bin/bash

declare -r SERVER_NAME="$1"
shift

for CONF_FILENAME in "${@}"; do
    awk -v servername="${SERVER_NAME}" '
    /^#+$/ {
        ndash = length($0)
        print
        next
    }
    /^# SERVER:/ {
        match($0, /[: ][^: #]*[ #]/, arr)
        fn = arr[0]
        gsub(/[: #]/, "", fn)
        str = "# " servername ":" fn
        nspace = ndash - length(str) - 1
        if (nspace < 1) { nspace = 1 }
        printf("%s%*.*s#\n", str, nspace, nspace, "")
        next
    }
    {
        print
    }
    ' "${CONF_FILENAME}" > "${CONF_FILENAME}.tmp"
    mv "${CONF_FILENAME}.tmp" "${CONF_FILENAME}"
done

Used like that:

./sysconf.sh sv4 /etc/rsyslog.conf /etc/mysql/mariadb.cnf
questor avatar
us flag
thanks, works fine. But one point is open. My script should change the header of config files for various services in multiple Containers, not only rsyslog. means /etc/rsyslog.conf is only and example and can not used as static string # SERVER:/etc/rsyslog.conf # # SERVER:/etc/mysql/mariadb.cnf # # SERVER:/etc/ldap/ldap.conf # in sed there are \1 \2 statements to keep a string if matched with a filter. not sure if similar is needed in awk.
Arnaud Valmary avatar
in flag
I have updated my solution for any filenames
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.