一 分隔字元
1.單個分隔字元(例將11:22:33字串取出11 22 33)
echo 11:22:33 | awk 'BEGIN{FS=":"};{print $1" "$2" "$3;};'
2.定義多個分隔字元(例將11:22#33&44字串取出11 22 33 44)
echo '11:22#33&44' | awk 'BEGIN{FS="[:#&]"};{print $1" "$2" "$3" "$4;};'
3.定義多個分隔字元字串(例將11:::22##33&&44字串取出11 22 33 44)
echo '11:::22##33&&44' | awk 'BEGIN{FS="(:::|##|&&)"};{print $1" "$2" "$3" "$4;};'
4.注意FS使用的是一個Regex表示,那麼如果有字串11##22,分隔字元為#會被分割成三個字串,$2是空的,假如#不定長那麼使用
echo '11##22' | awk 'BEGIN{FS="#+"};{print $1" "$2};'
5.那麼想分割例3那樣不定個:,#,&呢
echo '11:::22##33&&44' | awk 'BEGIN{FS="(:+|#+|&+)"};{print $1" "$2" "$3" "$4;};'
二 一個統計問題,下面統計所有A B C的總數 輸出A:總數 B:總數 ....
A=1B=20C=3C=-5A=4A=3D=8D=-9xx=11xx=22
1.這裡使用了關聯陣列sum[$1]和for迴圈
awk 'BEGIN{FS="=";};{sum[$1]+=$2;};END{for(key in sum){print key":"sum[key]}}' test
2.問題:如果上面出現了空行,那麼處理空行時需要跳過不處理呢?
awk 'BEGIN{FS="=";};!/^ *$/{sum[$1]+=$2;};END{for(key in sum){print key":"sum[key]}}' test
!/^ *$/表示只處理不是空白的行,
3.問題:如果加一行類似D=-9=33那不也有問題,所以要改下只處理兩個欄位的,對於其他欄位的輸出出錯行,這裡還是跳過空白行
awk 'BEGIN{FS="=";};!/^ *$/{if(NF==2){sum[$1]+=$2;}else{print "error line "NR":"$0;}};END{for(key in sum){print key":"sum[key]}}' test
4.問題:如果累加的數$2不是數字那麼是不是也應該跳過。
awk 'BEGIN{FS="=";};!/^ *$/{if(NF==2){if($2 !~ /^-*[0-9]+$/) next; sum[$1]+=$2;}else{print "error line "NR":"$0;}};END{for(key in sum){print key":"sum[key]}}' test
if($2 !~ /^-*[0-9]+$/) next;表示判斷整數不匹配則讀取一行(next)
5.問題:如果累加的數$2前後有空格怎麼辦,所以處理時先去除首尾的空格再判斷是否數字
awk 'BEGIN{FS="=";};!/^ *$/{if(NF==2){gsub("(^ *)|( *$)","",$2);if($2 !~ /^-*[0-9]+$/) next; sum[$1]+=$2;}else{print "error line "NR":"$0;}};END{for(key in sum){print key":"sum[key]}}' test
gsub("(^ *)|( *$)","",$2);表示去除頭和尾的空格後存至$2;同樣的也可以先對欄位1去除首尾空格