我在这个网站上尝试了无数的awk语法建议,但不知怎的,我无法理解awk ..
我正在尝试将两行(当前的一行和下一行)组合在一起,只有当我的expr存在于下一行时。
例如,我有一个包含以下内容的文本文件:
<option value="1" selected> channel 1
<div id="program_13" class="tree_3"><input type="checkbox" name="output_checkbox" value="13"> Somename1</div>
<option value="2" selected> channel 2
<div id="program_21" class="tree_3"><input type="checkbox" name="output_checkbox" value="21"> 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"> Somename1</div>
<option value="2" selected> channel 2 <div id="program_21" class="tree_3"><input type="checkbox" name="output_checkbox" value="21"> 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:
我期待着您的建议
答案 0 :(得分: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"> Somename1</div>
<option value="2" selected> channel 2
<div id="program_21" class="tree_3"><input type="checkbox" name="output_checkbox" value="21"> 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"> Somename1</div>
<option value="2" selected> channel 2 <div id="program_21" class="tree_3"><input type="checkbox" name="output_checkbox" value="21"> Someothername</div>
<option value="3" selected> channel 3
<option value="4" selected> channel 4
<option value="5" selected> channel 5
答案 1 :(得分:2)
我想出了以下内容:
/output_checkbox/ { sub(/\n/, "", last); printf "%s" last; print; last = "" }
!/output_checkbox/ { printf "%s" last; last = ($0 "\n"); }
END { printf "%s" last }
答案 2 :(得分:1)
最简单的方法是将前一行保留在变量中:
awk '/pattern/{print prev $0;prev="";next} prev{print prev} {prev=$0} END{print prev}'
正如@Kent指出的那样,问题规范存在一个模糊性:如果两个连续的行匹配/pattern/
,那么需要什么(我认为这不是OP中提出的实际问题中的问题。)< / p>
我的小程序假设意图是/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}'
注意:这两个程序都删除了空行。
答案 3 :(得分:1)
我对Awk没有任何线索,但是如果你想要一个正常的模式,这个可以工作:
.+?(channel .+?)(?:(?:\s|\z)+?.+? (.+?)</div>)?
结果将是:
channel 1 Somename1
channel 2 Someothername
channel 3
channel 4
channel 5
如果您想使用awk,这可以帮助您: http://www.unixcl.com/search/label/Awk