Replace multiple lines from a file with mutiple li

2019-09-16 18:46发布

Can I, in few commands, search and replace multiple lines in a file?

I'm trying to replace the 3 failover blocks from dhcp_primary by the unique failover block from dhcp_secondary, within dhcp_primary.

My goal is to copy the dhcpd.conf from a primary dhcp to the secondary (more information here: http://www.madboa.com/geek/dhcp-failover/). The failover work only if the configuration are identical, except the failover block of course; as you can see is the website's example. So I want to copy this file, but keep the failover information from the secondary.

Example dhcp_primary:

// some lines above
failover peer "A" {
...
}
failover peer "B" {
...
}
failover peer "C" {
...
}
// some lines below

Example dhcp_secondary:

// some different lines above
failover peer "D" {
...
}
// some different lines below

The expected output have to be:

// some lines above
failover peer "D" {
...
}
// some lines below

I already can extract the failover blocks :

awk '/^failover/,/^}$/' dhcp_a

awk '/^failover/,/^}$/' dhcp_b

But I don't know how to continue.

Thanks in advance.

Edit: more details for my goal.

4条回答
淡お忘
2楼-- · 2019-09-16 19:02
$ cat tst.awk
/^failover/ { inRec  = 1 }

{
    if (NR == FNR) {
        if (inRec) {
            rec = rec $0 ORS
        }
    }
    else {
        if (inRec) {
            printf "%s", rec
            rec = ""
        }
        else {
            print
        }
    }
}

/^}/ { inRec = 0 }

$ awk -f tst.awk secondary primary
// some lines above
failover peer "D" {
...
}
// some lines below
查看更多
淡お忘
3楼-- · 2019-09-16 19:14

You can try:

awk -f a.awk dhcp_b dhcp_a

where a.awk is:

/^failover/,/^}$/{
    if (NR==FNR) {
        blk=blk $0 RS
        next
    }
    if (++i==1) {
        printf "%s",blk
    }
    next
}
NR!=FNR{  print }
查看更多
对你真心纯属浪费
4楼-- · 2019-09-16 19:18

if the files are only of this structure and kind of content

NewFile=./FileName

head -1 dhcp_a > ${NewFile}
sed -n '1!{$!p;};}' dhcp_b >> ${NewFile}
tail -1 dhcp_a >> ${NewFile}

just take header and trailer of dhcp_a and block content of dhcp_b

if file is bigger (content around) use something like /failover/,/}/ as block delimiter in sed but it depend of the real content

查看更多
家丑人穷心不美
5楼-- · 2019-09-16 19:22

This might work for you (GNU sed):

sed -n '/^failover peer/,/^}/p' dhcp_b | 
sed -e '/^failover peer/,/^}/!b;r /dev/stdin' -e 'd' dhcp_a
查看更多
登录 后发表回答