2

我经常需要修改诸如 之类的文件sysctl.conf,而且我熟悉使用 sed 替换现有值。

如果 sed 无法替换它,有没有办法将新的键/值对附加到文件中?

例如,使用此示例:使用 bash 脚本修改配置文件

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

如何将$TARGET_KEY = $REPLACEMENT_VALUE新行添加到$CONFIG_FILE使用相同的 sed 表达式并稍作更改?

$CONFIG_FILE在相关主题上,如果它不存在,我该如何强制创建?

4

2 回答 2

4

您无法在一次sed通话中轻松完成所有操作。最简单的方法可能是两步:

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

但是,您可能应该做一些事情来使上述内容更加健壮:

  1. 您的正则表达式未锚定,这意味着尝试设置“PORT”也会找到/更改“SUPPORT”等。

  2. 如果配置文件可能有制表符和空格,它将不匹配

  3. 如果替换值中有斜线,则失败。

  4. 如果文件路径包含空格或 shell 元字符,您应该始终引用参数扩展$CONFIG_FILE,例如。

  5. 在这种情况下是安全的,但是当您需要文字反斜杠时,在双引号字符串中使用单个反斜杠可能会造成混淆。当 shell 无法识别其后的特殊序列时,shell 会将它们单独放置,但如果将它们加倍会更清楚。

  6. 你的 sed 版本有什么作用-c?我的 Linux 和 Mac 版本都不支持这样的选项。

所以我会这样做(^I's 代表文字制表符,而^A's 文字 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
于 2012-11-19T16:13:19.980 回答
0

使用下面的伪代码:

if (grep -q key); then
    sed...
else
    echo key=value >> $CONFIG_FILE
fi
于 2012-11-19T15:50:45.700 回答