awk編程的基本用法

awk也是用來處理文本的,awk語言能夠從文件或字符串中基於指定規則瀏覽和抽取信息,能夠實現數據查找、抽取文件中的數據、建立管道流命令等功能。正則表達式

awk模式匹配數組

第一種方法打印空白行
將空白行打印出來,並輸出this is a blank line.(有幾行空白行就打印幾行this is a blank line.)
awk '/^$/{print "this is a blank line."}' dim_ia_test.logbash

第二種方法調用awk打印空白行函數

cat scr.awk測試

/^$/{print "this is a blank line."}

執行命令:this

awk -f scr.awk dim_ia_test.logspa

命令結果:命令行

第三種方法打印空白行blog

cat scr1.awkip

#!/bin/awk -f
/^$/{print "this is a blank line."}

將執行權限賦予腳本:chmod u+x scr1.awk

執行命令:

./scr1.awk dim_ia_test.log  

執行結果:

 

awk之記錄和域

將第二列、第一列、第四列、第三列打印出來(默認以空格分割)
awk '{print $2,$1,$4,$3}' dim_ia_test2.log
將所有列都打印出來(默認以空格分割)
awk '{print $0}' dim_ia_test2.log
將第三列內容打印出來(默認以空格分割)
awk 'BEGIN {one=1;two=2}{print $(one+two)}' dim_ia_test2.log
等價
awk '{print $3}' dim_ia_test2.log
-F爲改變分隔符爲-,將第三列內容打印出來
awk -F"\-" '{print $3}' dim_ia_test2.log

 

awk之關係和布爾運算
awk關係運算符及其意義
< --小於
> --大於
<= --小於等於
>= --大於等於
== --等於
!= --不等於
~ --匹配正則表達式
!~ --不匹配正則表達式
匹配以:分割的第一個域是否含有Job,若是含有Job,則打印該行
awk 'BEGIN {FS=":"} $1~/Job/' dim_ia_test.log
所有域匹配05,並將含有05的行打印出來
awk 'BEGIN {FS=":"} $0~/05/' dim_ia_test.log
以:分割,若是知足第一個域小於第二個域,則打印該行的所有域
awk 'BEGIN {FS=":"}{if($1<$2) print $0}' dim_ia_test.log
 
awk布爾運算符及其意義
|| --邏輯或
&& --邏輯與
! --邏輯非
多條件精確匹配,以:分割,若是知足第一個域小於第二個域或者第二個域大於第三個域,則打印該行的所有域
awk 'BEGIN {FS=":"}{if($1<$2||$2>$3) print $0}' dim_ia_test.log
多條件模糊匹配,以:分割,若是知足第一個域含有數字3或者第二個域含有數字3,則打印該行的所有域
awk 'BEGIN {FS=":"}{if($1~3||$2~3) print $0}' dim_ia_test.log
 
awk之表達式
awk算術運算符及其意義
+ --加
- --減
* --乘
/ --除
% --模
^或** --乘方
++x --在返回x值以前,x變量加1
x++ --在返回x值以後,x變量加1
統計空白行,並以1,2,3,4………的形式打印出來
awk '/^$/{print x+=1}' dim_ia_test.log
統計空白行,並以0,1,2……的形式打印出來
awk '/^$/{print x++}' dim_ia_test.log
統計空白行,並以1,2……的形式打印出來
awk '/^$/{print ++x}' dim_ia_test.log
結果呈現:
 
 計算平均值的一個例子:
cat sturecord  --數據源
li ming,68,75,89,90
fang tianyi,60,90,70,80
fang xiaolong,81,72,64,95
fang tianxin,80,70,69,95

cat scr2.awk  --awk腳本

#!/bin/awk -f
BEGIN {FS=","}
{total=$2+$3+$4+$5
avg=total/4
print $1,total,avg}

賦給腳本執行權限

chmod u+x scr2.awk

執行腳本

./scr2.awk sturecord  

執行結果:

li ming 322 80.5
fang tianyi 300 75
fang xiaolong 312 78
fang tianxin 314 78.5

  

awk之系統變量
awk環境變量及其意義
$n --當前記錄的第n個域,域間由FS分隔
$0 --記錄的全部域
ARGC --命令行參數的數量
ARGIND --命令行中當前文件的位置(以0開始標號)
ARGV --命令行參數的數組
CONVFMT --數字轉換格式
ENVIRON --環境變量關聯數組
ERRNO --最後一個系統錯誤的描述
FIELDWIDTHS --字段寬度列表,以空格鍵分隔
FILENAME --當前文件名
FNR --瀏覽文件的記錄數
FS --字段分隔符,默認是空格鍵
IGNORECASE --布爾變量,若是是真,則進行忽略大小寫的匹配
NF --當前記錄中的域數量
NR --當前記錄數
OFMT --數字的輸出格式
OFS --輸出域分隔符,默認是空格鍵
ORS --輸出記錄分隔符,默認是換行符
RLENGHT --由math函數所匹配的字符串長度
RS --記錄分隔符,默認是空格鍵
RSTART --由math函數所匹配的字符串的第一個位置
SUBSEP --數組下標分隔符,默認值是\034
以,號分隔,輸出記錄中的域數量,當前記錄數,以及記錄的全部域
awk 'BEGIN {FS=","} {print NF,NR,$0} ' sturecord

5 1 li ming,68,75,89,90
5 2 fang tianyi,60,90,70,80
5 3 fang xiaolong,81,72,64,95
5 4 fang tianxin,80,70,69,95

以,號分隔,輸出記錄中的域數量,當前記錄數,以及記錄的全部域,最後輸出當前文件名

awk 'BEGIN {FS=","} {print NF,NR,$0} END {print FILENAME}' sturecord

5 1 li ming,68,75,89,90
5 2 fang tianyi,60,90,70,80
5 3 fang xiaolong,81,72,64,95
5 4 fang tianxin,80,70,69,95
sturecord

  

awk之格式化輸出
printf修飾符及其意義
- --左對齊
width --域的步長
.prec --小數點右邊的位數
printf格式符及其意義
%c --ASCII字符
%d --整數型
%e --浮點數,科學記數法
%f --浮點數
%o --八進制數
%s --字符串
%x --十六進制數
以,號分隔,格式化輸出第一列(字符串格式)、第二列(整型),第一列與第二列之間以tab間分隔,每行打印完即回車
awk 'BEGIN {FS=","} {printf("%s\t%d\n",$1,$2)}' sturecord
li ming 68
fang tianyi     60
fang xiaolong   81
fang tianxin    80
以,號分隔,格式化輸出第一列(字符串格式)、第二列(浮點型),第一列與第二列之間以tab間分隔,每行打印完即回車
awk 'BEGIN {FS=","} {printf("%s\t%f\n",$1,$2)}' sturecord
li ming 68.800000
fang tianyi     60.600000
fang xiaolong   81.300000
fang tianxin    80.600000

將65轉換爲ASCII字符
awk 'BEGIN {printf("%c\n",65)}'

A

以,號分隔,格式化輸出第一列(字符串格式)、第二列(整型),這裏第一列作了一個處理,-15表示該字符串長度控制在15位,而且左對齊,若字符串不足15位則用空格補全,第一列與第二列之間以tab間分隔,每行打印完即回車
awk 'BEGIN {FS=","} {printf("%-15s\t%f\n",$1,$2)}' sturecord

li ming         68.800000
fang tianyi     60.600000
fang xiaolong   81.300000
fang tianxin    80.600000

以,號分隔,格式化輸出第一列(字符串格式)、第二列(整型),咱們在輸出域上加了解釋語言,第一列作了一個處理,-15表示該字符串長度控制在15位,而且左對齊,若字符串不足15位則用空格補全,第一列與第二列之間以tab間分隔,每行打印完即回車
awk 'BEGIN {FS=",";print "NAME\t\tMATHSCORE"} {printf("%-15s\t%f\n",$1,$2)}' sturecord

NAME            MATHSCORE
li ming         68.800000
fang tianyi     60.600000
fang xiaolong   81.300000
fang tianxin    80.600000

以,號分隔,格式化輸出第一列(字符串格式)、第二列(浮點型,浮點型保留一位小數),第一列與第二列之間以tab間分隔,每行打印完即回車
awk 'BEGIN {FS=","} {printf("%s\t%.1f\n",$1,$2)}' sturecord  

li ming 68.8
fang tianyi     60.6
fang xiaolong   81.3
fang tianxin    80.6

以,號分隔,格式化輸出第一列(字符串格式)、第二列(浮點型,浮點型保留兩位小數),第一列與第二列之間以tab間分隔,每行打印完即回車
awk 'BEGIN {FS=","} {printf("%s\t%.2f\n",$1,$2)}' sturecord

li ming 68.80
fang tianyi     60.60
fang xiaolong   81.30
fang tianxin    80.60

以,號分隔,格式化輸出第一列(字符串格式)、第二列(浮點型,浮點型保留兩位小數,該浮點數長度控制在10位,且爲右對齊),第一列與第二列之間以tab間分隔,每行打印完即回車
awk 'BEGIN {FS=","} {printf("%s\t%10.2f\n",$1,$2)}' sturecord

li ming      68.80
fang tianyi          60.60
fang xiaolong        81.30
fang tianxin         80.60

總結printf修飾符的一版形式:%-width.prec格式控制符

 

awk以內置字符串函數
awk字符串函數及其意義
gsub(r,s) --在輸入文件中用s替換r
gsub(r,s,t) --在t中用s替換r
index(s,t) --返回s中字符串第一個t的位置
length(s) --返回s的長度
match(s,t) --測試s是否包含匹配t的字符串
split(r,s,t) --在t上將r分紅序列s
sub(r,s,t) --將t中第一次出現的r替換爲s
substr(r,s) --返回字符串r中從s開始的後綴部分
substr(r,s,t) --返回字符串r中從s開始長度爲t的後綴部分
首先指定域分隔符爲",",輸出的域分隔符爲":",而後將第一個域中的fang替換爲yuan,最後輸出所有域,將含有yuan的全部行顯示出來
awk 'BEGIN {FS=",";OFS=":"} gsub(/fang/,"yuan",$1) {print $0}' sturecord 

yuan tianyi:60.6:90:70:80
yuan xiaolong:81.3:72:64:95
yuan tianxin:80.6:70:69:95

ph在gridsphere中第六位開始出現
awk 'BEGIN {print index("gridsphere","ph")}'

6

gridsphere的長度是10
awk 'BEGIN {print length("gridsphere")}' 

10

測試D是否包含匹配字符串gridsphere,返回0爲不包含
awk 'BEGIN {print match("gridsphere",/D/)}'

0

忽略大小寫後,測試D是否包含匹配字符串gridsphere,返回4說明包含,d出如今第四個位置
awk 'BEGIN {IGNORECASE=1;print match("gridsphere",/D/)}'

4

先定義str變量,使用sub函數將第一次出現的pro定義成PRO
awk 'BEGIN {str="multiprocessor programming";sub(/pro/,"PRO",str);printf("%s\n",str)}'

multiPROcessor programming

將sturecord中第一號域與fang匹配的記錄中的第一次出現的60改爲99
awk 'BEGIN {FS=","}{$1~fang sub(/80/,"99",$0);print $0}' sturecord

li ming,68.8,75,89,90
fang tianyi,60.6,90,70,99
fang xiaolong,81.3,72,64,95
fang tianxin,99.6,70,69,95

截取str從第六個字符開始的後綴部分
awk 'BEGIN {str="multiprocessor programming";print substr(str,6)}'  

processor programming

截取str從第六個字符開始的長度爲9的後綴部分
awk 'BEGIN {str="multiprocessor programming";print substr(str,6,9)}'  

processor

 

向awk腳本傳遞參數

cat pass.awk

#!/bin/awk -f
NF!=MAX
{print ("The line "NR" does not have "MAX" filds.")}

賦權 chmod u+x pass.awk

執行命令:./pass.awk MAX=3 FS="," sturecord

li ming,68.8,75,89,90
The line 1 does not have 3 filds.
fang tianyi,60.6,90,70,80
The line 2 does not have 3 filds.
fang xiaolong,81.3,72,64,95
The line 3 does not have 3 filds.
fang tianxin,80.6,70,69,95
The line 4 does not have 3 filds.

輸出sturecord的全部記錄,每行記錄前加上其行號,從新定義OFS的值,改變輸出域的分隔符
awk 'BEGIN {FS=","} {print NR,$0}' OFS=";" sturecord 

1;li ming,68.8,75,89,90
2;fang tianyi,60.6,90,70,80
3;fang xiaolong,81.3,72,64,95
4;fang tianxin,80.6,70,69,95

  

awk之條件語句和循環語句
條件語句if的語法
if(條件表達式)
  動做1
  [else
  動做2]
樣例
awk 'BEGIN {if (x==y) print "x與y相等"}' x=1 ;y=1
 
三種循環
while(條件表達式)
    動做
 
do
  動做
while(條件表達式)
 
for(設置計數器初值;測試計數器;計數器變化)
   動做

awk之數組
將原始定義的數組打印出來
awk 'BEGIN{data[10.15]="1200";printf("<%s>\n",data[10.15])}'
關鍵字in用於判斷元素10.15是否在數組中,若是存在,則輸出found element!
awk 'BEGIN{data[10.15]="1200";if("10.15" in data) print "found element!"}'
將abc/def/lih分紅3個元素存儲在數組str中
awk 'BEGIN{print split("abc/def/lih",str,"/")}' 

3

將第一個域按空格拆分,存到name數組中
awk 'BEGIN{FS=","}{print split($1,name," ")}' sturecord

2
2
2
2

演示split所生成的數組

查看腳本:cat array.awk  

#!/bin/awk -f
BEGIN {FS=","}
{split($1,name," ");
for(i in name) print name[i]}

賦權: chmod u+x array.awk

執行:./array.awk sturecord

li
ming
fang
tianyi
fang
xiaolong
fang
tianxin

等價於:awk 'BEGIN{FS=","}{split($1,name," ");for(i in name)print name[i]}' sturecord      

相關文章
相關標籤/搜索