2014-08-28 3 views
1

У меня есть файл A: config nginx. Где-то в этом файле у меня есть {here}Замените строку содержимым файла

Я хочу заменить, что {here} содержанием другого файла В:

location /blah { 
    proxy_pass "https://blah.com"; 
} 

Я попытался с СЭД и AWK (GSUB), но у меня есть проблемы с символом return/unescaped.

Я нашел решение, но только работает только с рисунком, не работает с заменой. В этом примере будет добавлять FILEB после моих маркеров вместо того, чтобы заменить его:

sed -i '/{here}/{r fileB 
:a;n;ba}' nginx.conf 
+1

Возможный дубликат [Вставить текст в файл после определенного текста] (http://stackoverflow.com/questions/25556211/insert-text-into-file-after-a-specific-text). Я просто ответил на этот вопрос, и это очень похоже. Техника awk, в частности, должна работать. –

+0

На самом деле, это немного другое, я все равно отправил ответ. –

ответ

2

Это следует сделать это:

awk 'NR==FNR { a[n++]=$0; next } 
/{here}/ { for (i=0;i<n;++i) print a[i]; next } 
1' fileB fileA 

Построить массив, содержащий все строки файла, содержащего замену. Когда шаблон сопоставляется во втором файле, распечатайте все строки. В противном случае 1 в конце означает, что печатаются исходные строки.

Как справедливо указал Эд, инициализатор цикла ошибочен. Я изменил его на i=0, чтобы напечатать первую строку. Кроме того, это заменяет все содержимое строки, содержащей {here}, что может быть или не быть тем, что вам нужно.

Для перезаписи исходного файла, вы можете сделать:

awk '...' fileB fileA > tmp && mv tmp fileA 
+0

Спасибо за это решение awk! Мне было бы очень интересно увидеть альтернативу тому, что я написал. – Bastien974

+0

Нет проблем. Возможно, кто-то с лучшими навыками sed, чем я, сможет предоставить решение sed. –

+0

Это должно быть '++ n' вместо' n ++ ', поэтому массив начинается с 1 вместо 0, а затем цикл должен заканчиваться на' <= n'. Сейчас он пропустит печать первой строки файлаB. Это не заменяет '{here}' содержимым файла B, оно заменяет всю строку, содержащую '{here}'. –

0

Это может работать для вас (GNU СЭД):

sed 's/\(.*\){here}\(.*\)/echo '\''\1'\''$(cat fileB)'\''\2'\''/e' fileA 
+0

Я пробовал, он не сохраняет символ возврата в файлеB. Если я правильно понимаю, вы захватываете то, что есть до и после шаблона, и повторяете их вокруг fileB. Тем не менее, я немного потерял во всех этих одиночных кавычках. – Bastien974

2

Все, что вам нужно:

awk 'NR==FNR{rep=(NR>1?rep RS:"") $0; next} {gsub(/{here}/,rep)}1' fileB nginx.conf 

если fileB не содержит &, так как они будут интерпретироваться операцией замены как строка соответствия RE. Если это так, используйте в цикле index() и substr().

Если {here} является ТОЛЬКО на линии, расскажите нам об этом, поскольку это делает проблему немного проще.

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