如果第1行和第2行都不以;开头,则合并这两行为新行,并继续处理新行和第3行;
如果第1行以;开头,则继续处理第2行和第3行。
以上流程仅为方便描述,只要能达到相同效果即可。
如输入为:
;a
;;b
c
d;
e;;;
;f
g
期望输出:
;a
;;b
cd;e;;;
;f
g
大家讲道理2017-04-17 12:07:30
awk '!/^;/{a=arrreee}/^;/{if(a!="")print a;print rrreee;a="";}END{if(a!="")print a;}'
awk語法 test1{statements1}test2{statements2}...
針對每一行
,若符合test1,則執行statement1,若滿足test2,執行statement2 ...
所以分3部分:
!/^;/{a=a;
}
如果不以a
開頭,則將目前行追加到臨時變數!/^;/
!
/.../
^;
;
正規表示式,表示以a=a
a
a
/^;/{if(a!="")print a;print ;
;a="";}
a
/^;/
(若有),再輸出目前行;
if(a!="")print a;print
;a="";
if(a!="")print a;
print
a="";
a
如果a不為空,則輸出a的值(print自動換行)END{if(a!="")print a;}
的值,以備下次使用a
;
a
處理完所有行,最後再判斷緩衝區;
中是否有內容,若有,則列印END
BEGIN
如果最後幾行都不以PHP中文网2017-04-17 12:07:30
首先: 將換行符號去掉,/n//g
然後: 判斷字母序列右邊是否有數字,有則在右邊加上換行符/([a-z]+)(?=[0-9]+)/1/n/g
判斷字母序列左側是否有數字,有則在左側加上換行符/([a-z]+)(?<=[0-9]+)//n1/g
最後: 將上面正規表示式用sed
或awk
實現。
天蓬老师2017-04-17 12:07:30
awk版本
awk 'sed -n '/^;/{H;x;s/^\n//g;p;s/.*//g;x;};/^;/!{H;x;s/\n//g;x};${/^;/!p}' urfile!~ /^;/{a=arrreee;}/^;/{print a?a"\n"rrreee:rrreee;a=""}END{if(a)print a}' urfile
再附加一個sed的
rrreeePHPz2017-04-17 12:07:30
這種略複雜的需求,用sed/awk是可以實現,但是我覺得不推薦,這時候一般用python或perl來做更有效率。
不過為了看看我的sed功底還在不在,還是試了一下,目前簡單測試沒有發現問題,程式碼如下:
sed -r -n '/^;/!{h;s/.*//;x;:l $!{H;n;/^;/!b l};x;s/\n//gp;g};p'
解釋幾個重點的部分:
1. h;s/.*//;x;
是為了清空hold space
2. :l $!{H;n;/^;/!b l};
部分是一個循環,將所有的非;
開頭的行合併到hold space,退出條件有兩個:到達最後一行或遇到一個;
開頭的行
3. x;s/n//gp;g
將hold space中的內容去掉換行符並列印出來
4. 最後p
列印pattern space中的內容,用來列印;
開頭的行
答案還沒寫完,發現一個bug了: 如果檔案的最後有2行以上的非;
開頭的行,最後一行沒有被合併。
修改一下原來的答案為:
sed -r -n '/^;/!{h;s/.*//;x;:l $!{H;n;/^;/!b l};/^;/!{H;g;s/\n//gp;t};x;s/\n//gp;g};p'
修改說明:
1. 跳出迴圈之後,判斷目前行如果不是;
開頭(根據先前的跳出條件可知,這是最後一行),將目前行加入hold space,然後處理hold space的內容
看吧,一個其實也不是很複雜的需求,用sed來寫,命令越寫越長,1個月後還能一眼看懂麼?這類需求還是不要用sed來做吧