2013-09-16 5 views
1

У меня есть 2 файла: старого_файл и NewFile, которые сходны по структуре, они содержат лишь незначительные измененияSed заменить блоки текста из 2-х файлов

Мне нужно заменить блок текста из NewFile с блоком из старый_файла (как Баш скрипт)

в старый_файл у меня есть:

... текст

####################################################################### 
# 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 = **** 

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

... другой текст

newfile идентичен только значениям параметров.

Я использовал СЭД получить этот выход из старый_файла как это: getldap = sed -n '/^# LDAP Settings$/,/^$/p' oldfile > ldap.tmp (он сохраняет ее в ldap.tmp)

используется разделители: Настройки # LDAP и пустая строка, содержащий пробел

Теперь я хочу вставить этот вывод в новый файл и заменить существующий аналогичный текст.

+0

что ваш вопрос или проблема тогда? –

ответ

4

Правильный инструмент для правильной работы, здесь awk будет удовлетворять вашим требованиям намного лучше, чем sed.

Это AWK должно работать:

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

Update: Для того, чтобы ограничить замены до # LDAP Settings только вы можете сделать:

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 

Объяснение:

Эта команда AWK может быть разделен на 2 секции:

-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 
+0

Извините, но это не работает, если я правильно понимаю, это должно заменить все значения после [=], но я хочу только этот блок, есть другие значения, которые я не хочу заменять. Также, когда я запускаю его, он ничего не делает в изменениях в новом файле. – anarchist

+0

Отправьте образец нового файла. Также awk не изменяет новый файл, вам нужно перенаправить вывод в отдельный файл, а затем переместить его обратно в новый файл e.g 'awk -F '[=] +' 'FNR == NR {a [$ 1] = $ 0; next} $ 1 в {$ 0 = a [$ 1]} 1' oldfile newfile> _temp && mv _temp newfile' – anubhava

+0

Ok это работает в некоторой степени: он успешно заменяет блок, но есть другие строки с =, и в конце я получаю много ненужных данных в новом файле – anarchist

2

Следующая sed команда заменит раздел Настройки LDAP с содержимым ldap.tmp:

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

Спасибо, это работает, только проблема в том, что я получаю 2 строки LDAP Settings – anarchist

+0

вы можете удалить строку настроек LDAP из ldap.tmp? – dogbane

+0

Я не уверен, как это сделать, если я использую другой разделитель, такой как LDAPUrl =, то у меня нет вывода в моем файле tmp – anarchist

Смежные вопросы