如何最好地使用 SED 注释掉一个配置值并在其后立即添加一个新的配置值?

如何最好地使用 SED 注释掉一个配置值并在其后立即添加一个新的配置值?

我想在 CLI 中编辑一些配置文件,不用所见即所得编辑器,而是使用sed

有没有最佳做法来做到这一点?

以下是我所指的几个例子:

配置文件示例 1

配置文件中的一行可能是这样的:

foo_option /bar/baz

编辑后应如下所示:

#foo_option /bar/baz
foo_option /new/opt

配置文件示例 2

配置文件中的一行可能是这样的:

foo_option=/bar/baz

编辑后应如下所示:

#foo_option=/bar/baz
foo_option=/new/opt

我认为流编辑器sed是首选工具,我已经对它进行过实验:

sed -e 's/\(^foo_option .*$\)/#\1/' /path/to/conf.file

和:

sed -e 's/^foo_option .*$/foo_option /new/opt/' /path/to/conf.file

但是我怎样才能同时进行这两项更改(两行,一行注释掉,一行包含新内容)?

这真的是最佳做法sed吗?

答案1

我不知道这是否是“最佳实践”,但这sed方面的代码相对简单:

sed '/^foo_option / {s/^/#/; a\
foo_option /new/opt
}' /path/to/conf.file

它解决了示例 1。要解决示例 2,您需要在代码foo_option中用 替换每个出现的(有两次出现,请注意尾随空格)。foo_option=sed

=解决这两个示例的通用代码更复杂,因为您附加的内容取决于旧行中的存在;因此您不能使用a固定字符串。试试这个:

sed '/^foo_option[= ]/ {
  h; s/^/#/; p
  g; s|\([= ]\).*|\1/new/opt|
}' /path/to/conf.file

上述代码两次使用了原始行。首先,它将行从模式空间复制到保留空间 ( h),将其添加#到前面并打印模式空间 ( p)。接下来,它从保留空间 ( g) 复制回来并放置/new/opt在正确的位置;这次打印模式空间,因为sed(没有-n) 在处理完行后默认会​​打印(不需要p)。

笔记:

  • |在第二个中使用了s,而不是/,因为/new/opt包含/。您尝试使用s/^foo_option .*$/foo_option /new/opt/无效,字符太多/。一般来说您可以使用几乎任何字符

  • 在您尝试时,您^foo_option在模式中使用了s来匹配正确的行;然后您需要在替换中使用它(作为\1或文字foo_option)。更好的方法是使用正则表达式匹配来处理行,就像我所做的那样:/^foo_option /或 so。然后以下命令(或{ }块)不需要检查它是否是正确的行,您知道它是正确的。您可以使用s; 以外的命令,并且s通常可以大大简化。即使在添加的简单情况下,#我也更喜欢/^foo_option / s/^/#/s/\(^foo_option \)/#\1/前者的代码更具可读性,而且是正确的方法。

  • 在正则表达式中*是贪婪的,所以.*$(你使用它)并不真正需要$

相关内容