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

左心房为你撑大大i 提交于 2019-12-01 23:11:33

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

Use below pseudo code:

if (grep -q key); then
    sed...
else
    echo key=value >> $CONFIG_FILE
fi
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!