2012-08-24 30 views
0

我有兩個文件:更換或與另一個文件的較量追加文本塊文件

super.conf

someconfig=23; 
second line; 

#blockbegin 
dynamicconfig=12 
dynamicconfig2=1323 
#blockend 

otherconfig=12; 

input.conf

newdynamicconfig=12; 
anothernewline=1234; 

我想運行一個腳本,並input.conf替換#blockbegin#blockend行之間的內容。

我已經有這樣的:

sed -i -ne '/^#blockbegin/ {p; r input.conf' -e ':a; n; /#blockend/ {p; b}; ba}; p' super.conf 

它運作良好,但直到我更改或刪除#blockendsuper.conf,那麼腳本#blockbegin後替換所有行。


另外,我想腳本,如果塊不存在super.conf追加新的塊一起super.confinput.conf內容替換塊。 它可以通過刪除+ append來完成,但是如何使用sed或其他unix命令刪除塊?

+0

當你刪除'#blockend'時,你期望看到什麼? – perreal

+0

沒有'#blockend'腳本的@perreal不應該改變任何東西。或者在第二種情況下添加新塊(不更改以前的內容)。 – rogal111

回答

0

我寫的Perl一行代碼:

perl -0777lni -e 'BEGIN{open(F,pop(@ARGV))||die;$b="#blockbegin";$e="#blockend";local $/;$d=<F>;close(F);}s|\n$b(.*)$e\n||s;print;print "\n$b\n",$d,"\n$e\n" if eof;' edited.file input.file 

參數:

edited.file - 路徑更新的文件 input.file - 與塊的新內容的文件路徑

腳本首先刪除塊(如果找到一個匹配)並且接下來將新塊添加到新的內容。

-1

你的意思是說

sed '/^#blockbegin/,/#blockend/d' super.conf 
+0

您是否閱讀過我的所有問題?使用'#blockbegin'和不帶'#blockend'的文件試試這個:它會刪除'#blockbegin'的所有行到文件結尾! – rogal111

+0

在這種情況下,它如何知道要刪除的內容和行數。 – Satish

+0

在這種情況下,它不應該刪除任何東西......它應該像正則表達式刪除:'/#blockbegin(。*)#blockend/gsm' – rogal111

1

雖然我得問題這個方案的效用 - 我傾向於認爲大聲抱怨時,期望得不到滿足,而不是更加loosey,鵝這樣的系統 - 我相信下面的腳本會做你想做的。

操作理論:它先讀入所有東西,然後一次性發出它的輸出。

假設您將文件名稱injector稱爲injector input.conf super.conf

#!/usr/bin/env awk -f 
# 
# Expects to be called with two files. First is the content to inject, 
# second is the file to inject into. 

FNR == 1 { 
    # This switches from "read replacement content" to "read template" 
    # at the boundary between reading the first and second files. This 
    # will of course do something suprising if you pass more than two 
    # files. 
    readReplacement = !readReplacement; 
} 

# Read a line of replacement content. 
readReplacement { 
    rCount++; 
    replacement[rCount] = $0; 
    next; 
} 

# Read a line of template content. 
{ 
    tCount++; 
    template[tCount] = $0; 
} 

# Note the beginning of the replacement area. 
/^#blockbegin$/ { 
    beginAt = tCount; 
} 

# Note the end of the replacement area. 
/^#blockend$/ { 
    endAt = tCount; 
} 

# Finished reading everything. Process it all. 
END { 
    if (beginAt && endAt) { 
     # Both beginning and ending markers were found; replace what's 
     # in the middle of them. 
     emitTemplate(1, beginAt); 
     emitReplacement(); 
     emitTemplate(endAt, tCount); 
    } else { 
     # Didn't find both markers; just append. 
     emitTemplate(1, tCount); 
     emitReplacement(); 
    } 
} 

# Emit the indicated portion of the template to stdout. 
function emitTemplate(from, to) { 
    for (i = from; i <= to; i++) { 
     print template[i]; 
    } 
} 

# Emit the replacement text to stdout. 
function emitReplacement() { 
    for (i = 1; i <= rCount; i++) { 
     print replacement[i]; 
    } 
} 
+0

好的工作,我用等價的單行腳本添加了答案; - ) – rogal111

相關問題