bash 使用bash脚本修改配置文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2464760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:04:37  来源:igfitidea点击:

Modify config file using bash script

bashconfiguration-files

提问by Progress Programmer

I'm writing a bash script to modify a config file which contains a bunch of key/value pairs. How can I read the key and find the value and possibly modify it?

我正在编写一个 bash 脚本来修改包含一堆键/值对的配置文件。如何读取密钥并找到值并可能对其进行修改?

回答by Cascabel

A wild stab in the dark for modifying a single value:

暗中修改单个值的疯狂尝试:

sed -c -i "s/\($TARGET_KEY *= *\).*/$REPLACEMENT_VALUE/" $CONFIG_FILE

assuming that the target key and replacement value don't contain any special regex characters, and that your key-value separator is "=". Note, the -c option is system dependent and you may need to omit it for sed to execute.

假设目标键和替换值不包含任何特殊的正则表达式字符,并且您的键值分隔符是“=”。请注意,-c 选项取决于系统,您可能需要省略它才能执行 sed。

For other tips on how to do similar replacements (e.g., when the REPLACEMENT_VALUE has '/' characters in it), there are some great examples here.

有关如何进行类似替换的其他提示(例如,当 REPLACEMENT_VALUE 中包含 '/' 字符时),这里有一些很好的示例

回答by Rudi Strydom

Hope this helps someone. I created a self contained script, which required config processing of sorts.

希望这可以帮助某人。我创建了一个自包含脚本,它需要各种配置处理。

#!/bin/bash
CONFIG="/tmp/test.cfg"

# Use this to set the new config value, needs 2 parameters. 
# You could check that  and  is set, but I am lazy
function set_config(){
    sudo sed -i "s/^\(\s*=\s*\).*$//" $CONFIG
}

# INITIALIZE CONFIG IF IT'S MISSING
if [ ! -e "${CONFIG}" ] ; then
    # Set default variable value
    sudo touch $CONFIG
    echo "myname=\"Test\"" | sudo tee --append $CONFIG
fi

# LOAD THE CONFIG FILE
source $CONFIG

echo "${myname}" # SHOULD OUTPUT DEFAULT (test) ON FIRST RUN
myname="Erl"
echo "${myname}" # SHOULD OUTPUT Erl
set_config myname $myname # SETS THE NEW VALUE

回答by vladr

Assuming that you have a file of key=valuepairs, potentially with spaces around the =, you can delete, modify in-place or append key-value pairs at will using awkeven if the keys or values contain special regex sequences:

假设您有一个key=value成对文件,可能在 周围有空格=awk即使键或值包含特殊的正则表达式序列,您也可以随意删除、就地修改或附加键值对:

# Using awk to delete, modify or append keys
# In case of an error the original configuration file is left intact
# Also leaves a timestamped backup copy (omit the cp -p if none is required)
CONFIG_FILE=file.conf
cp -p "$CONFIG_FILE" "$CONFIG_FILE.orig.`date \"+%Y%m%d_%H%M%S\"`" &&
awk -F '[ \t]*=[ \t]*' '=="keytodelete" { next } =="keytomodify" { print "keytomodify=newvalue" ; next } { print } END { print "keytoappend=value" }' "$CONFIG_FILE" >"$CONFIG_FILE~" &&
mv "$CONFIG_FILE~" "$CONFIG_FILE" ||
echo "an error has occurred (permissions? disk space?)"

回答by ghostdog74

sed "/^$old/s/\(.[^=]*\)\([ \t]*=[ \t]*\)\(.[^=]*\)/$replace/" configfile

回答by tempcke

So I can not take any credit for this as it is a combination of stackoverflow answers and help from irc.freenode.net #bash channel but here are bash functions now to both set and read config file values:

所以我不能相信这一点,因为它是 stackoverflow 答案和来自 irc.freenode.net #bash 频道的帮助的组合,但现在这里有 bash 函数来设置和读取配置文件值:

# https://stackoverflow.com/a/2464883
# Usage: config_set filename key value
function config_set() {
  local file=
  local key=
  local val=${@:3}

  ensureConfigFileExists "${file}"

  # create key if not exists
  if ! grep -q "^${key}=" ${file}; then
    # insert a newline just in case the file does not end with one
    printf "\n${key}=" >> ${file}
  fi

  chc "$file" "$key" "$val"
}

function ensureConfigFileExists() {
  if [ ! -e "" ] ; then
    if [ -e ".example" ]; then
      cp ".example" "";
    else
      touch ""
    fi
  fi
}

# thanks to ixz in #bash on irc.freenode.net
function chc() { gawk -v OFS== -v FS== -e 'BEGIN { ARGC = 1 }  == ARGV[2] { print ARGV[4] ? ARGV[4] : , ARGV[3]; next } 1' "$@" <"" >".1"; mv ""{.1,}; }

# https://unix.stackexchange.com/a/331965/312709
# Usage: local myvar="$(config_get myvar)"
function config_get() {
    val="$(config_read_file ${CONFIG_FILE} "")";
    if [ "${val}" = "__UNDEFINED__" ]; then
        val="$(config_read_file ${CONFIG_FILE}.example "")";
    fi
    printf -- "%s" "${val}";
}
function config_read_file() {
    (grep -E "^=" -m 1 "" 2>/dev/null || echo "VAR=__UNDEFINED__") | head -n 1 | cut -d '=' -f 2-;
}

at first I was using the accepted answer's sed solution: https://stackoverflow.com/a/2464883/2683059

起初我使用的是公认答案的 sed 解决方案:https: //stackoverflow.com/a/2464883/2683059

however if the value has a / char it breaks

但是,如果该值有一个 / char 它会中断

回答by tempcke

in general it's easy to extract the info with grep and cut:

一般来说,使用 grep 和 cut 很容易提取信息:


cat "$FILE" | grep "^${KEY}${DELIMITER}" | cut -f2- -d"$DELIMITER"

to update you could do something like this:

要更新,您可以执行以下操作:


mv "$FILE" "$FILE.bak"
cat "$FILE.bak" | grep -v "^${KEY}${DELIMITER}" > "$FILE"
echo "${KEY}${DELIMITER}${NEWVALUE}" >> "$FILE"

this would not maintain the order of the key-value pairs obviously. add error checking to make sure you don't lose your data.

这显然不会保持键值对的顺序。添加错误检查以确保您不会丢失数据。

回答by datasunny

Suppose your config file is in below format:

假设您的配置文件采用以下格式:

CONFIG_NUM=4
CONFIG_NUM2=5
CONFIG_DEBUG=n

In your bash script, you can use:

在您的 bash 脚本中,您可以使用:

CONFIG_FILE=your_config_file
. $CONFIG_FILE

if [ $CONFIG_DEBUG == "y" ]; then
    ......
else
    ......
fi

$CONFIG_NUM, $CONFIG_NUM2, $CONFIG_DEBUGis what you need.

$CONFIG_NUM, $CONFIG_NUM2,$CONFIG_DEBUG正是您所需要的。

After your read the values, write it back will be easy:

读取值后,将其写回将很容易:

echo "CONFIG_DEBUG=y" >> $CONFIG_FILE