Append or modify keys in conf files using sed/bash one-liner

﹥>﹥吖頭↗ 提交于 2019-12-02 03:12:44

问题


I often have to modify files such as sysctl.conf, and I'm familiar with using sed to replace existing values.

Is there a way to append the new key/value pair to the file if sed wasn't able to replace it?

For instance, using this example: modify config file using bash script

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

How could I add the $TARGET_KEY = $REPLACEMENT_VALUE new line to $CONFIG_FILE using the same sed expression with slight changes?

And on a related topic, how can I force creation of $CONFIG_FILE if it didn't exist?


回答1:


You can't easily do it all in a single sed call. It's probably simplest to make it two steps:

if grep -q "$TARGET_KEY *= " $CONFIG_FILE; then   
   sed -c -i "s/\($TARGET_KEY *= *\).*/\1$REPLACEMENT_VALUE/" $CONFIG_FILE
else
   echo "$TARGET_KEY = $REPLACEMENT_VALUE" >>$CONFIG_FILE
fi

There are a few things you should probably do to make the above more robust, however:

  1. Your regular expression is not anchored, which means that trying to set 'PORT' will also find/change 'SUPPORT', etc.

  2. It won't match if the config file might have tabs as well as spaces

  3. It fails if the replacement value has slashes in it.

  4. You should always quote parameter expansions like $CONFIG_FILE, in case the file path contains spaces or shell metacharacters.

  5. It's safe in this instance, but potentially confusing to use single backslashes in a double-quoted string when you want a literal backslash. The shell leaves them alone when it doesn't recognize what comes after it as a special sequence, but it would be clearer if you doubled them.

  6. What does -c do on your version of sed? Neither my Linux nor Mac versions support such an option.

So I would do it this way (the ^I's represent literal tab characters, and the ^A's literal control-A characters, entered by for example typing control-V first on the command line):

if grep -q "^[ ^I]*$TARGET_KEY[ ^I]*=" "$CONFIG_FILE"; then
   sed -i -e "s^A^\\([ ^I]*$TARGET_KEY[ ^I]*=[ ^I]*\\).*$^A\\1$REPLACEMENT_VALUE^A" "$CONFIG_FILE"
else
   echo "$TARGET_KEY = $REPLACEMENT_VALUE" >> "$CONFIG_FILE"
fi



回答2:


Use below pseudo code:

if (grep -q key); then
    sed...
else
    echo key=value >> $CONFIG_FILE
fi


来源:https://stackoverflow.com/questions/13456564/append-or-modify-keys-in-conf-files-using-sed-bash-one-liner

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!