2010-03-17 76 views
35

我在写一个bash脚本来修改一个包含一堆键值对的配置文件。我如何阅读密钥并找到它的价值并修改它?使用bash脚本修改配置文件

+0

我试着回答这个在这里https://stackoverflow.com/a/47509618/3343801 – 2017-11-27 11:17:17

回答

72

在黑暗中野生刺修改单值:

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

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

有关如何进行类似替换的其他提示(例如,当REPLACEMENT_VALUE中有'/'字符时),there are some great examples here

+7

-c在我的环境中似乎无效。当我摆脱-c时,它会起作用。谢谢。 – 2010-03-17 21:48:18

+0

'-c'选项告诉sed在文件洗牌时(而不是重命名)复制文件 - 它可以防止更改所有权并使用只读文件搞乱。我已经选择了一种习惯来拯救自己免受愚蠢的错误(尤其是使用find | | xargs sed -i')的习惯。 – Cascabel 2010-03-17 22:04:19

+1

我真的为这个答案得到两个赞成吗?我不仅设法猜测OP的想法,而且简短有效。任何人都在意解释? – Cascabel 2010-03-18 00:10:23

-1

假设您的配置文件是在以下格式:

CONFIG_NUM=4 
CONFIG_NUM2=5 
CONFIG_DEBUG=n 

在你的bash脚本,你可以使用:

CONFIG_FILE=your_config_file 
. $CONFIG_FILE 

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

$CONFIG_NUM$CONFIG_NUM2$CONFIG_DEBUG是你所需要的。

你以后读值,写回会很容易:

echo "CONFIG_DEBUG=y" >> $CONFIG_FILE 
+6

这不会替换值,只需再次在底部添加它,它是完全依赖于配置文件是一个有效的bash脚本,以及...哇,如果在配置文件中有恶意的东西会怎么样? – Cascabel 2010-03-17 18:29:42

1
一般

很容易提取使用grep的信息和削减:


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

更新,你可以做这样的事情:


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

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

+0

如果磁盘空间不足,或者由于某种原因无法创建'FILE',那么您的解决方案将会遗留'FILE'(必须手动将'FILE.bak'重命名为'FILE'才能恢复。) – vladr 2010-03-17 21:08:39

+0

你打赌。这就是为什么我写'添加错误检查'等:) – 2010-03-22 20:43:33

0

假设你有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]*' '$1=="keytodelete" { next } $1=="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?)" 
2
sed "/^$old/s/\(.[^=]*\)\([ \t]*=[ \t]*\)\(.[^=]*\)/\1\2$replace/" configfile 
10

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

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

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