用regex替换配置文件

时间:2018-03-13 08:22:47

标签: regex sed

我有文件unbound.conf

如下

## Simple recursive caching DNS, UDP port 53
## unbound.conf -- https://calomel.org
#
server:
   access-control: 10.0.0.0/8 allow
   verbosity: 1

forward-zone:
      name: "."
      forward-addr: 8.8.4.4        # Google
      forward-addr: 8.8.8.8        # Google

forward-zone:
      name: "example.com"
      forward-addr: 50.116.23.211  # Open

some-other-config:
      key: "value"

我从变量说FORWARD_ZONES获得前向区域,其样本值为

forward-zone:
      name: "somedns.com"
      forward-addr: 1.1.1.1
      forward-addr: 2.2.2.2

forward-zone:
      name: "someotherdns.com"
      forward-addr: 3.3.3.3
      forward-addr: 4.4.4.4

我需要删除conf文件中的所有前向区域,并根据收到的输入json数组创建新区域。

因此,在应用正则表达式结束时,我希望基于以上输入进行跟踪

## Simple recursive caching DNS, UDP port 53
## unbound.conf -- https://calomel.org
#
server:
   access-control: 10.0.0.0/8 allow
   verbosity: 1

forward-zone:
      name: "somedns.com"
      forward-addr: 1.1.1.1
      forward-addr: 2.2.2.2

forward-zone:
      name: "someotherdns.com"
      forward-addr: 3.3.3.3
      forward-addr: 4.4.4.4

some-other-config:
      key: "value"

我应该使用什么正则表达式使用sed来实现上述

sed -i "whatShouldBeRegexStringHereThatUses_FORWARD_ZONES_variable" unbound.conf

编辑: 这是一个操场,也展示了我做了什么 https://regex101.com/r/x0H2p3/1/

3 个答案:

答案 0 :(得分:0)

我相信可以通过以下方式awk实现这一目标:

awk 'BEGIN{p=1}
     /^[-a-zA-Z]*:[[:blank:]]*$/{p=1}
     /^forward-zone:[[:blank:]]*$/{p=0}
     (p==0&&v==0){print var;print ""; v=1}
     p' var=$FORWARD_ZONES foo.conf

如果需要打印一行,它基本上会检查变量p。如果它找到带有正则表达式^[-a-zA-Z]*:[[:blank:]]*$的新配置块,则它将默认设置printflag p=1,但是如果配置块为^forward-zone:[[:blank:]]*$,它将禁用打印。第一次禁用打印时,它会注入$FORWARD_ZONES

如果您的前方区域位于另一个名为forward_zones.conf的文件中,那么您可以使用

awk 'BEGIN{p=1}
     /^[-a-zA-Z]*:[[:blank:]]*$/{p=1}
     /^forward-zone:[[:blank:]]*$/{while(getline line<f2){print line); p=0}
     (p==0&&v==0){print ""; v=1}
     p' f2=forward_zones.conf foo.conf

答案 1 :(得分:0)

在GNU sed中:sed -e "/forward-zone/,/^\s*$/d;/some-other/i $FORWARD_ZONES" input-file

使用/START/,/END/d/some-other/i插入$FORWARD_ZONES

的内容,可以相对简单地删除现有的前区部分

示例输出:

$ export FORWARD_ZONES="newjunk\nnewjunk\n"

$ sed -e "/forward-zone/,/^\s*$/d;/some-other/i $FORWARD_ZONES" fz.txt

server:
   access-control: 10.0.0.0/8 allow
   verbosity: 1

newjunk
newjunk

some-other-config:
      key: "value"

如果您希望使用GNU sed插入另一个文件的内容,可以插入new.txt

sed -e "/forward-zone/,/^\s*$/d;/some-other/e cat new.txt" fz.txt

使用GNU sed e命令转出cat new.txt,该命令会立即附加到输出流中。

非GNU sed可能需要i之后的换行符,并且不支持e命令。简单的解决方法是创建一个用于sed -f的命令文件。

答案 2 :(得分:0)

以下为我工作

sed -zri 's/(forward-zone:\s*\n\s*name: \".*\"\s*\n\s*(forward-addr: [0-9\.]*.*\s*\n\s*)+\s*\n\s*)+/$FORWARD_ZONES/' unbound.conf

我需要获得有效的正则表达式 https://regex101.com/r/x0H2p3/2

然后使用sed和

'-z'
'--null-data'
'--zero-terminated'
     Treat the input as a set of lines, each terminated by a zero byte
     (the ASCII 'NUL' character) instead of a newline.  This option can
     be used with commands like 'sort -z' and 'find -print0' to process
     arbitrary file names.

'-E'
'-r'
'--regexp-extended'
     Use extended regular expressions rather than basic regular
     expressions.  Extended regexps are those that 'egrep' accepts; they
     can be clearer because they usually have fewer backslashes.
     Historically this was a GNU extension, but the '-E' extension has
     since been added to the POSIX standard
     (http://austingroupbugs.net/view.php?id=528), so use '-E' for
     portability.  GNU sed has accepted '-E' as an undocumented option
     for years, and *BSD seds have accepted '-E' for years as well, but
     scripts that use '-E' might not port to other older systems.  *Note
     Extended regular expressions: ERE syntax.