2

このサイトで awk 構文について無数の推奨事項を試しましたが、どういうわけか awk について理解できません。

expr が次の行に存在する場合にのみ、2 つの行 (現在の行と次の行) を結合しようとしています。

たとえば、次の内容を含むテキスト ファイルがあります。

<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

私はsedを使って最後に次のものを手に入れたいと思っています(これは私が扱うことができると思います):

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

あなたの提案を楽しみにしています

4

4 に答える 4

3

この行を試してください:

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
于 2013-09-27T16:00:22.503 に答える
1

最も簡単な方法は、前の行を変数に保持することです。

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

@Kent が指摘しているように、問題の仕様にはあいまいさがあります。2 つの連続する行が一致する場合に何が望まれるか/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}'

注: これらのプログラムは両方とも空白行を削除します。

于 2013-09-27T16:01:14.733 に答える
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

于 2013-09-27T16:48:15.993 に答える