使用 sed 从多个字符串中删除双斜杠(当前想法不起作用)

使用 sed 从多个字符串中删除双斜杠(当前想法不起作用)

我正在尝试替换以下项目中的双反斜杠 (//):

//listen-on port 53 { 127.0.0.1; };
//listen-on-v6 port 53 { ::1; };
//recursion yes;

(我不知道是否有必要提及,但这些结果前面有几个空格。可能没有必要,但无论如何我还是想提一下。)

我对 sed 的了解有限(而且我不想使用其他任何东西),但出于某种原因,我无法将其删除。我也尝试使用“|”作为分隔符(或它的名称),但没有成功。

我尝试过的事情:

sed -i 's|^//recursion yes;*|recursion yes;*|' /etc/named.conf

和:

sed 's#^//[ \t]recursion$#recursion#g' /etc/named.conf

sed 's#^//[\t]recursion$#recursion#g' /etc/named.conf

(最后两个例子基于我在本网站某个不同主题中发现的内容,但也没有给出正确的结果。换句话说,它拒绝删除两个斜线(//)。

到目前为止,我只尝试使用“//recursion yes;”,因为我想先让它工作,但是我已经失败了。

请解释一下我做错了什么。谢谢!如果您愿意,有人也可以给出一个 awk 示例吗?这样我就可以将其用作 sed 的替代品。显然 awk 比 sed 更受欢迎?或者这只是个人偏好?

答案1

我不知道是否有必要提及,但这些结果前面有几个空格。可能没有必要,但无论如何我还是想提一下。

这非常重要 -如果用来^将匹配模式锚定到字符串的开头。特别是:

  • ^//recursion只会在开头完全匹配
  • ^//[ \t]recursion//仅当正好位于开头且后面只有一个空格或制表符时才会匹配
  • ^//[\t]recursion//仅当正好位于开头且后面紧跟一个制表符时才会匹配

此外,你似乎对*正则表达式的含义感到困惑(与 shell glob 或通配符不同) - 在正则表达式中,它是一个量词表示零个或多个前面的表达式。

假设空格在之前//,我可能会这样做

sed -E '\:[ \t]*//recursion|listen-on: s://::' named.conf

分解

  • \:^[ \t]*//recursion|listen-on:匹配零个或多个空格或制表符,后跟//thenrecursionlisten-on

  • s://:://仅在匹配的行上不进行任何替换

我使用:它代替默认值的分隔符/以避免与模式字符串混淆,并删除了-i用于测试的。-E启用扩展匹配,这使得|平均值or

如果需要在 的两边允许任意空格//,则可以将匹配表达式更改为

\:^[ \t]*//[ \t]*(recursion|listen-on):

如果愿意,您也可以使用[[:blank:]]代替(甚至还包括垂直空格 - 在这种情况下,区别是没有意义的,因为您一次只处理一行)。[ \t][[:space:]]


使用 awk 时,情况会略有不同 - 至少如果您使用默认字段分隔符。在这种情况下,awk 会删除前导空格,因此您可以将 锚定//到第一个字段的开头:

awk '$1 ~ /\/\/recursion/ {sub(/\/\//,"",$1)} 1'

请注意,只有 GNU awk 提供就地编辑选项。在 awk 中,您还可以考虑使用固定字符串匹配,例如

'$1 == "//recursion" || $1 == "//listen-on"

还要注意,这些方法都会从输出中去除前导空格。

相关内容