如何根据下一行中存在的模式组合当前行和下一行。 (使用awk)

我已经尝试了awk语法在这个网站无数的build议,但不知何故,我不能让我的头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”expression式时才join下一行。 这可能是对所有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: 

我期待着您的build议

试试这一行:

 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 

我想出了以下几点:

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

最简单的方法是将上一行保留在变量中:

 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/ lines被附加,产生:

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

为了得到这个结果,做一个简单的修改:

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

注:这两个程序都删除空白行。

我对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