用于更新 BIND ACL 的 Bash 脚本-不需要的字符

用于更新 BIND ACL 的 Bash 脚本-不需要的字符

我正在尝试更新服务器上的一个文件,其中新行需要在前面有一个制表符,但是对于 bash 脚本和 sed 来说却是新手,并且在前面不断出现不需要的字符。

这是 sed 命令:

sed -i "/acl \"trusted\" {/a&\t$ACL_IP;    # $SRV_HOST_NAME" $ACL_CONF_FILE

In the results I get :
&       192.12.12.12;    # SERVER
        192.13.13.13;    # SERVER1
        192.14.14.14;    # SERVER2

Instead of :
       192.12.12.12;    # SERVER
       192.13.13.13;    # SERVER1
       192.14.14.14;    # SERVER2

我也尝试了以下操作但收到未知命令错误:

sed -i "/acl \"trusted\" {/$ACL_IP    # $SRV_HOST_NAME;\r\n\tacl \"trusted\" {/" $ACL_CONF_FILE

我也尝试过:

sed -i "/acl \"trusted\" {/a/\t$ACL_IP;    # $SRV_HOST_NAME" $ACL_CONF_FILE

但得到:

/       192.12.12.12;    # SERVER

希望我已经接近了,但就是看不到摆脱多余的角色。

答案1

因此,您正在尝试使用(GNU 扩展)a text命令来Atext匹配后附加。但是,在这种情况下,您的 以制表符开头,由转义序列text表示。sed\t

不幸的是,还有一种(符合 POSIX 标准的)形式A附加命令,其中反斜杠字符将a命令与分开text。因此,当您写入时,a\t它会附加一个文字 t&。您可以通过放置一个额外的字符(首先是,然后是/)将反斜杠与命令分开来“解决”该问题a- 但这只会导致这些字符按字面意思附加。

为了解决歧义,您需要将命令传递为a\\t。不幸的是,由于您在整个 sed 表达式周围使用了双引号(以允许扩展 shell 变量),因此 shell 将扩展\\\;要传递,\\您需要转义两个反斜杠:

sed "/acl \"trusted\" {/a\\\\t$ACL_IP;    # $SRV_HOST_NAME"

或者,用单引号括住不需要 shell 扩展的部分:

sed '/acl "trusted" {/a\\t'"$ACL_IP;    # $SRV_HOST_NAME"

\t另一个选项是用文字制表符替换转义序列,使用Ctrl+ Vthen组成TAB。您仍然必须使用a\命令的形式,因为 GNU 扩展a text形式会忽略前导空格。


或者(也许更干净),您可以使用命令从标准输入r读取格式化的字符串:printf

printf '\t%s;    # %s\n' "$ACL_IP" "$SRV_HOST_NAME" |
  sed -i '/acl "trusted" {/r/dev/stdin' "$ACL_CONF_FILE"

相关内容