awk命令

1.awk命令

awk的設計使得他非常適合處理由行列組成的文本數據。awk還是一種編程語言環境,他提供了正則表達式的匹配,流程控制,運算符,表達式,變量,以及函數等一系列的程序設計語言所具備的特性。



2.awk命令的基本語法

awk命令的基本語法:

awk  匹配模式  { 執行的操作 }



2.1 awk的工作流程

awk處理數據時,他會反覆執行一下4個步驟:

1.自動的從數據文件中讀取文本的行。

2.自動更新 awk 的內置系統變量的值。例如:列數變量NF,行數變量NR,行變量$0,各個變量$1,$2等。

3.依次執行程序中的所有的匹配模式及其操作。

4.當執行完程序的所有匹配模式和操作後,如果數據文件中仍有未讀取的數據行,則返回第一步重複執行1~4的操作。



2.2 awk的執行方式

用戶通過3種方式來執行awk程序,分別是命令行,awk腳本,可執行文件。

命令行語法 awk  'awk程序語句'  待處理的文件 。例如:awk '{ print }' a.txt

awk腳本語法 awk  -f  awk腳本  待處理的文件 。awk腳本里依次寫上awk程序語句即可。

可執行腳本語法 awk腳本 待處理的文件 。但是一定要指定命令解釋器 #! /bin/awk -f 。腳本內容依次寫上awk的程序語句即可。



2.3 特殊字符

$0:表示整個當前行 

$1:每行第一個字段 

NF:字段數量變量 

NR:每行的記錄號,多文件記錄遞增 

FNR:與NR類似,不過多文件記錄不遞增,每個文件都從1開始 

FS:BEGIN時定義分隔符,默認是空格或製表符。

RS:輸入的記錄分隔符,默認是換行符。awk每次讀取一行進行處理,通過指定行分隔符,來決定awk一次讀取多少行。例如:指定行分隔符爲空行,awk每次讀取有空格的地方。

\t:製表符 

\n:換行符 

~ :匹配,與==相比不是精確比較 

!~:不匹配,不精確比較 

== :等於,必須全部相等,精確比較 

!= :不等於,精確比較 

&&:邏輯與 

||: 邏輯或 

+:匹配時表示1個或1個以上 

/[0-9][0-9]+/: 兩個或兩個以上數字 

/[0-9][0-9]*/ : 一個或一個以上數字 

OFS:輸出字段分隔符, 默認也是空格,可以改爲製表符等 

ORS:輸出的記錄分隔符,默認爲換行符,即處理結果也是一行一行輸出到屏幕 

-F ':' :指定分隔符



3.awk的模式匹配

awk的匹配模式主要包括關係表達式,正則表達式,混合模式,BEGIN模式,END模式等。



3.1 關係表達式

awk提供了許多關係運算符,例如大於> ,小於< ,等於==等,awk可以以關係表達式作爲匹配模式,當文本行滿足關係表達式時,則會執行響應的操作。


實例:

顯示第二段大於80的行。

# awk '$2 > 80 { print }' 1.txt

q       90

e       86

r       84

y       98

表示第二列的值大於80,執行花括號裏面的 print 操作。



3.2 正則表達式

awk支持正則表達式匹配,和sed一樣,需要放在兩條斜線 /xx/ 之間。


實例:

# awk '/^(w|r)/ { print }' 1.txt  

w       75

r       84

表示匹配w或r 並 print 出來。



3.3 混合模式

awk支持關係表達式和正則表達式,同時支持使用邏輯運算符。

&&:邏輯與

||:邏輯或

!:邏輯非


實例:

# awk '/^w/ && $2 > 70 { print }' 1.txt    

w       75

兩條匹配模式都爲真,纔會顯示。


# awk '/^w/ || /^r/ { print }' 1.txt

w       75

r       84

兩條匹配模式哪條爲真顯示哪條。都爲真都顯示。



3.4 區間模式

區間模式是顯示兩條匹配模式之間的文本行。格式如下:

匹配模式1,  匹配模式2


實例:

匹配root開頭的行和UID爲3之間的行。-F指定分隔符。

# awk -F ":" '/^root/, $3==3 { print }' passwd

root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin



3.5 BEGIN模式

BEGIN模式是一種內置的模式,該模式裏的內容生命週期只會被執行一次,一般用在腳本里面。語法如下:

#! /bin/awk -f

BEGIN {

執行的操作1

執行的操作2

...

}

{ 對待處理的文件執行的操作 }

寫成一行就是:

awk 'BEGIN { 執行的操作1; 執行的操作2; } { 對待處理的文件執行的操作 }'  待處理的文件


實例:

只使用BEGIN模式顯示內容。

# awk 'BEGIN { print "aaa"; print "=======" }'

aaa

=======


使用BEGIN模式同時文件進行操作。

# awk 'BEGIN { print "aaa"; print "=======" } { print }' 1.txt  

aaa

=======

q       90

w       75

e       86



3.6 END模式

END模式也生命週期只會執行一次。一般會把善後的工作放在END模式對應模塊裏。在執行END模塊之前,必須執行操作或者執行BEGIN模式, 語法如下:

#! /bin/awk -f

{ 對待處理的文件執行的操作 }

END {

執行的操作1

執行的操作2

...

}

寫成一行就是:

awk ' { 對待處理的文件執行的操作 }  END { 執行的操作1; 執行的操作2; }'  待處理的文件


實例:

執行END模式,前面必須有操作,不然不能執行。

# awk '{ print } END { print "aaa"; print "=======" }' 1.txt

q       90

w       75

e       86

aaa

=======


執行BEGIN模式和END模式

# awk 'BEGIN { print "aaa"; print "=======" } END { print "======="; print "aaa" }' 1.txt  

aaa

=======

=======

aaa



4. 變量

awk的變量包括自定義的變量和系統內置變量。



4.1 自定義變量和引用

要放在BEGIN模式裏面,不然不會執行成功。引用變量直接跟變量名即可。

# awk 'BEGIN { x=3; print x }'

3



4.2 系統內置變量

變量

說明

$0

表示當前整個文件的內容

$n

n是整數,表示字段,每行第N個字段 

NF

表示當前記錄的字段數,字段總數

NR

每行的記錄號,多文件記錄遞增,總行數

FNR

與NR類似,不過多文件記錄不遞增,每個文件都從1開始 

OFS

寫在條件的前面,用來指定print顯示的列之間的分隔符。例如:awk -F ":" '{OFS="#"} $1=="root"  {print $1,$2,$3,$4}' test.txt

FILENAME

表示正在處理的數據文件的名稱

FS

字段分隔符,默認是空格或製表符

RS

行分隔符,默認是換行符。awk每次讀取一行進行處理,通過指定行分隔符,來決定awk一次讀取多少行。例如:指定行分隔符爲空行,awk每次讀取有空格的地方。



4.3 內置變量行分隔符FS 字段分隔符RS

awk對文本進行處理是一行一行選取的,然後對文本行進行處理。

因爲系統變量FS默認的分隔符是換行符“\n”,如果更改換行符則會每次讀取到換行符的位置。

一般把 FS 和 RS 放在BEGIN 模塊裏面。


實例1:

指定A爲分割符,所以在處理後的A都換行符,而不出現了。

ccc下面的空格是文件本身的換行符\n。

# cat 1.txt

aaaAbbbAccc

# awk '{ print } { print "===="}' 1.txt //正常顯示

aaaAbbbAccc

====

# awk 'BEGIN { RS="A" } { print }{ print "===="}' 1.txt //指定RS之後

aaa

====

bbb

====

ccc

====


實例2:

把A當做字段分割符,顯示第一段,則第一個A前面的內容爲第一個字段符。

# cat 1.txt

a a a A b b b A c c c

# awk  '{ print $1 }' 1.txt //正常顯示

a

# awk 'BEGIN { FS="A" } { print $1 }' 1.txt //指定FS之後。空格不再是分隔符了。

a a a


實例3:

匹配第三段大於500的行,print 第137段,分隔符用#。

# awk -F ":" '$3>500 { print $1"#"$3"#"$7}' test.txt

nfsnobody#4294967294#/sbin/nologin

mysql#501#/sbin/nologin

# awk -F ":" '{OFS="#"}$3>500 { print $1,$3,$7}' test.txt      

nfsnobody#4294967294#/sbin/nologin

mysql#501#/sbin/nologin



4.4 記錄$0 ,字段$n 的引用

在awk中,用戶可以使用系統變量引用記錄和字段。

雖然awk每次讀取的是一行,但在程序中記錄和字段的引用都是針對當前整個文件或數據流來說的。也就是如果要顯示第一段會顯示整個文件的第一段。


實例1:

變量$0的值就是當前的記錄值,可以說是當前文件或者數據流的內容。

# awk '{ print $0 }' 1.txt  

wang    85      92      79      87

li      89      90      73      82

zhao    81      88      92      81


實例2:

$1 $2 $3 分別代表第一列 第二列 第三列的數值。可以使用變量把數值的值相加。

# awk '{ print $1, $2+$3+$4+$5}' 1.txt

wang 343

li 334

zhao 342



5.運算符和表達式

5.1 算術運算符

運算符

說明

舉例

+

加法

1+2,表示求1和2的和,得3

-

減法

2-1,表示求2和1的差,得1

*

乘法

2*5,表示求2和5的積,得10

/

除法

6/2,表示求6和2的商,得3

%

求餘

5/2,表示求5除以2的餘,得1

^

冪運算

2^3,表示求2的3次方,得8


實例:

# awk ' BEGIN { print 3^2 , 5%2 , 5/2 , 2*3 } '

9  1  2.5  6



5.2 賦值運算

運算符

說明

舉例

=

賦值

x=5,表示給x賦值爲5

+=

前後相加後,再賦值給變量

x+=5,表示x的值加上5,再賦值給x,等價x=x+5

-=

前數值減後面數值,再賦值給變量

x-=5,表示x的值減5,再賦值給x

*=

前後相乘後,再賦值給變量

x*=5,表示x的值乘5,再賦值給x

/=

前數值除以後面數值,再賦值給變量

x/=5,表示x的值除以5,再賦值給x

%=

前數值除以後面數值的餘,賦值給變量

x%=5,表示x的值除以5的餘數,再賦值給x

^=

前數值的後面數值的次方,賦值給變量

x^=5,表示x的值的5次方,再賦值給x


實例:

# awk ' BEGIN { print x=5 , x+=5 , x%=6 , x*=3 } '

5 10 4 12



5.3 條件運算符

即當表達式的值爲真時,返回數值1,否則返回數值2。語法如下:

變量=(表達式?"數值1":"數值2")

print 變量


實例:

判斷打印成績單中的數值是否大於85,大於90的給A,否則給B。

# awk '{ a=($2>85?"A":"B"); print a }' 1.txt  

B

A

B

# awk '{ a=($2>85?"A":"B"); print $1,a }' 1.txt

wang B

li A

zhao B



5.4 邏輯運算符

awk支持3種邏輯運算,分別是邏輯與,邏輯或和邏輯非。

運算符

說明

舉例

&&

邏輯與,兩個表達式都爲真時,運行結果才爲真

1>2&&3>2的值爲假

||

邏輯或,有一個爲真,運行結果爲真。兩個表達式都爲假時,運行結果爲假

1>2||3>2的值爲真

!

邏輯非,當表達式爲真是,運行結果爲假。當表達式爲假時,運行結果爲真

!(1>2)的值爲真


實例:

當所有字段的數值都大於80時,才顯示出來。

# awk '$2 > 80 && $3 > 80 && $4 > 80 && $5 > 80 { print } ' 1.txt  

zhao    81      88      92      81



5.5 關係運算

awk支持關係運算一般有:大於,小於,等於 等..

運算符

說明

舉例

>

大於

5>2的值爲真

>=

大於等於

8>=8的值爲真

<

小於

5<6的值爲真

<=

小於等於

5<=7的值爲真

==

等於

5==5的值爲真

!=

不等於

1!=2的值爲真

~

匹配

$1~/^T/表示匹配第一個字段以字符T開頭的記錄

!~

不匹配

$1!~/a/表示匹配第一個字段不包含字符a的記錄

匹配運算符~ 不匹配運算符!~是awk特有的關係運算符,語法如下:

字符串 ~ 表達式

字符串 !~ 表達式

匹配運算符:判斷字符串中是否包含表達式的字符串。

不匹配運算符:判斷字符串中是否不包含表達式的字符串。



實例:

匹配第一個字符l開頭的記錄。

# awk '$1~/^l/ { print }' 1.txt

li      89      90      73      82

匹配前十行,第一段包含是root或者lp的行

# awk -F ":" 'NR<=10 && $1 ~ /root|lp/' test.txt  

root:x:0:0:root:/root:/bin/bash

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章