anarchist
anarchist

Reputation: 393

Sed replace blocks of text from 2 files

I have 2 files: oldfile and newfile which are similar in structure, they only contain minor changes

I need to replace a block of text from newfile with a block from the oldfile (as a bash script)

In oldfile I have:

... text

#######################################################################
# LDAP Settings
LDAPUrl = ldap://xxx
LDAPSearchBase = CN=Users,DC=xx,DC=xxx,DC=xx
LDAPSearchSecondary = ***
LDAPSearchFilter = cn=xxx
LDAPUser = CN=***,CN=Users,DC=xx,DC=xxx,DC=xx
LDAPPassword = ***
LDAPAuthenticateServer = ldap://test:389
ProsourceKey = ****

#######################################################################

... other text

newfile is identical only parameters values are changed.

I used sed the get this output from the oldfile like this: getldap=sed -n '/^# LDAP Settings$/,/^$/p' oldfile > ldap.tmp (it stores it in ldap.tmp)

used the delimiters: # LDAP Settings and the empty line that contains a space

Now I want to insert that output into newfile and replace the existing similar text.

Upvotes: 1

Views: 440

Answers (2)

anubhava
anubhava

Reputation: 785246

Right tool for the right job, here awk will suite your requirements much better than sed.

This awk should work:

awk -F '[= ]+' 'FNR==NR{a[$1]=$0;next} $1 in a{$0=a[$1]}1' oldfile newfile

Update: To restrict replacements to # LDAP Settings only you can do:

awk -F '[= ]+' 'FNR==NR && /^# LDAP Settings$/{r=1;next} FNR==NR && r && /^$/{r=0;next} 
   r && FNR==NR{a[$1]=$0;next} FNR!=NR{if($1 in a)$0=a[$1];print}' oldfile newfile

Explanation:

This awk command can be divided into 2 sections:

-F '[= ]+' - Use field separator = or space or both
FNR == NR - First file is being processed
FNR != NR - Second file is being processed
FNR == NR && /^# LDAP Settings$/ - In 1st file if # LDAP Settings is found set r=1
r && FNR==NR - a[$1]=$0 - In 1st file if r=1 then
a[$1]=$0 - Store 1st field as key in array a and $0 (whole line) as value
FNR==NR && r && /^$/ - In 1st file if r=1 and empty line found then set r=0

FNR!=NR{if($1 in a)$0=a[$1];print} In 2nd file if $1 exists in a then set whole line as 
                                   value of array a. Then print the whole line

Upvotes: 4

dogbane
dogbane

Reputation: 274622

The following sed command will replace the LDAP Settings section with the contents of ldap.tmp:

sed '/^# LDAP Settings$/,/^$/ {//!d}; /^# LDAP Settings$/r ldap.tmp' newfile

Upvotes: 2

Related Questions