2013-09-27 22 views
2

我已經嘗試了awk語法在這個網站的無數建議,但不知何故我不能讓我的頭在awk附近..如何根據下一行中存在的模式組合當前行和下一行。 (使用awk)

我想結合兩行(當前的一個和下一個)當我的expr存在於下一行時。

比如我有一個包含以下內容的文本文件:

<option value="1" selected> channel 1 
<div id="program_13" class="tree_3"><input type="checkbox" name="output_checkbox" value="13">&nbsp; &nbsp;Somename1</div> 
<option value="2" selected> channel 2 
<div id="program_21" class="tree_3"><input type="checkbox" name="output_checkbox" value="21">&nbsp; &nbsp;Someothername</div> 
<option value="3" selected> channel 3 
<option value="4" selected> channel 4 
<option value="5" selected> channel 5 

我想加盟,只有當「output_checkbox」表達下一行中存在下一個當前行。這可能是所有或任何5條主線的真相。

在上面的例子中,我期望的結果將是:

<option value="1" selected> channel 1 <div id="program_13" class="tree_3"><input type="checkbox" name="output_checkbox" value="13">&nbsp; &nbsp;Somename1</div> 
<option value="2" selected> channel 2 <div id="program_21" class="tree_3"><input type="checkbox" name="output_checkbox" value="21">&nbsp; &nbsp;Someothername</div> 
<option value="3" selected> channel 3 
<option value="4" selected> channel 4 
<option value="5" selected> channel 5 

我希望通過中美戰略經濟對話(我想我能處理),以獲得在末尾以下內容:

channel 1: Somename1 
channel 2: Someothername 
channel 3: 
channel 4: 
channel 5: 

我期待着您的建議

回答

4

嘗試這一行:

awk '/output_checkbox/{printf "%s",$0;next}{printf (NR>1?"\n%s":"%s"), $0}END{print ""}' file 

小測試:

kent$ cat f 
<option value="1" selected> channel 1 
<div id="program_13" class="tree_3"><input type="checkbox" name="output_checkbox" value="13">&nbsp; &nbsp;Somename1</div> 
<option value="2" selected> channel 2 
<div id="program_21" class="tree_3"><input type="checkbox" name="output_checkbox" value="21">&nbsp; &nbsp;Someothername</div> 
<option value="3" selected> channel 3 
<option value="4" selected> channel 4 
<option value="5" selected> channel 5 

kent$ awk '/output_checkbox/{printf "%s",$0;next}{printf (NR>1?"\n%s":"%s"), $0}END{print ""}' f 
<option value="1" selected> channel 1 <div id="program_13" class="tree_3"><input type="checkbox" name="output_checkbox" value="13">&nbsp; &nbsp;Somename1</div> 
<option value="2" selected> channel 2 <div id="program_21" class="tree_3"><input type="checkbox" name="output_checkbox" value="21">&nbsp; &nbsp;Someothername</div> 
<option value="3" selected> channel 3 
<option value="4" selected> channel 4 
<option value="5" selected> channel 5 
1

最簡單的方法是隻保持前行的變量:

awk '/pattern/{print prev $0;prev="";next} prev{print prev} {prev=$0} END{print prev}' 

由於@Kent指出,存在問題規範的歧義:是什麼如果連續兩行匹配/pattern/(我認爲這在OP中提出的實際問題中不是問題)。

我的小程序假定其意圖是/pattern/僅在前一行本身不匹配/pattern/時纔會附加到前一行。因此,它會變成:

<line>1 
<pattern>2 
<pattern>3 

<line>1<pattern>2 
<pattern>3 

但還有另一種解釋,所有/pattern/行追加,生產:

<line>1<pattern>2<pattern>3 

爲了得到這一結果,一個簡單的修改:

awk '/pattern/{prev = prev $0; next} prev{print prev} {prev=$0} END{print prev}' 

注意:這兩個程序都刪除空白行。

+0

如果有連續的'/ patter /'行可能會有問題 – Kent

+0

@Kent:我想這取決於在這種情況下需要什麼。在上面,我明確地重置'prev'以避免重複,但替代方法是用'{prev = prev $ 0; next}' – rici

+0

您的UPDATE中的命令不會給出該結果。它覆蓋了'{prev = $ 0}'中的'prev'。你需要找到正確的輸出點。無論如何,你的第一個單線可能已經解決了OP的問題.... – Kent

2

我想出了以下內容:

/output_checkbox/ { sub(/\n/, "", last); printf "%s" last; print; last = "" } 

!/output_checkbox/ { printf "%s" last; last = ($0 "\n"); } 

END { printf "%s" last } 
+1

從不使用printf作爲格式參數的輸入數據,否則當輸入包含格式化字符時(例如'%s'),您會得到令人討厭的驚喜。使用'printf'%s「last」,而不是'printf last'。 –

+0

好點,我會更新我的答案。 –

1

我不知道awk中的線索,但如果你想有一個正常的模式,這個會的工作:

.+?(channel .+?)(?:(?:\s|\z)+?.+? &nbsp;(.+?)</div>)? 

結果將是:

channel 1 Somename1 
channel 2 Someothername 
channel 3 
channel 4 
channel 5 

如果你想用awk,這可以幫助你: http://www.unixcl.com/search/label/Awk

+0

如果存在「output_checkbox」表達式,則不檢查該條件 – jkshah

+0

這不需要。看看他的帖子他想要什麼作爲最終結果。它的Exept來自:完全一樣! – Teifun2

相關問題