简体   繁体   English

使用sed / bash一线追加或修改conf文件中的密钥

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

I often have to modify files such as sysctl.conf , and I'm familiar with using sed to replace existing values. 我经常不得不修改sysctl.conf文件,并且我熟悉使用sed替换现有值。

Is there a way to append the new key/value pair to the file if sed wasn't able to replace it? 如果sed无法替换新的键/值对,是否可以将其添加到文件?

For instance, using this example: modify config file using bash script 例如,使用此示例: 使用bash脚本修改配置文件

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? 如何使用相同的sed表达式对$TARGET_KEY = $REPLACEMENT_VALUE新行添加到$CONFIG_FILE ,但要稍作更改?

And on a related topic, how can I force creation of $CONFIG_FILE if it didn't exist? 在一个相关的主题上,如果$CONFIG_FILE不存在,该如何强制它创建呢?

You can't easily do it all in a single sed call. 您无法在单个sed调用中轻松完成所有操作。 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. 您的正则表达式未锚定,这意味着尝试设置“ PORT”也会发现/更改“ SUPPORT”等。

  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. 如果文件路径包含空格或外壳程序元字符,则应始终引用$CONFIG_FILE类的参数扩展名。

  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? -c对您的sed版本有什么作用? Neither my Linux nor Mac versions support such an option. 我的Linux和Mac版本都不支持该选项。

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): 因此,我将以这种方式进行操作( ^I代表文字制表符,而^A代表文字control-A字符,例如通过在命令行上首先键入control-V来输入):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM