【現(xiàn)學(xué)現(xiàn)忘&Shell編程】— 34.AWK編程之a(chǎn)wk內(nèi)置變量

1、awk內(nèi)置變量

awk內(nèi)置變量 作用
$0 代表目前awk所讀入的整行數(shù)據(jù)。我們已知awk是一行一行讀入數(shù)據(jù)的,$0就代表當(dāng)前讀入行的整行數(shù)據(jù)。
$n 代表目前讀入行的第n個字段。
NF 當(dāng)前行擁有的字段(列)總數(shù)。
NR 當(dāng)前awk所處理的行,是總數(shù)據(jù)的第幾行。
FS 用戶定義分隔符。awk的默認(rèn)分隔符是任何空格(tab鍵或者空格),如果想要使用其他分隔符(如“:”),就需要FS變量定義。
ARGC 命令行參數(shù)個數(shù)。
ARGV 命令行參數(shù)數(shù)組。
FNR 當(dāng)前文件中的當(dāng)前記錄數(shù)(對輸入文件起始為1)。
OFMT 數(shù)值的輸出格式(默認(rèn)為%.6g)。
OFS 輸出字段的分隔符(默認(rèn)為空格)。
ORS 輸出記錄分隔符(默認(rèn)為換行符)。
RS 輸入記錄分隔符(默認(rèn)為換行符)。

2、練習(xí)說明

(1)$n練習(xí)

使用如下文本

ID      Name    Python  Linux   MySQL   Java
1       Tangs   88      87      86      85.55   
2       Sunwk   99      98      97      96,66   
3       Zhubj   77      76      75      74.44   
4       Shahs   66      65      64      63.33 

比如我們提取文本中的第2列數(shù)據(jù),執(zhí)行如下命令:

[root@localhost tmp]# awk '{printf $2 "\n"}' student.txt 
Name
Tangs
Sunwk
Zhubj
Shahs

(2)FS練習(xí)

awk的默認(rèn)分隔符是任何空格(tab鍵或者空格),如果想要使用其他分隔符,就需要FS變量定義。

cut命令默認(rèn)是以tab鍵做為分隔符。

我們之前用cut命令提取過/etc/passwd文件中普通用戶的用戶名,現(xiàn)在我們來用awk來提取能正常登陸用戶的用戶名。

執(zhí)行如下命令:

[root@localhost tmp]# cat /etc/passwd | grep "/bin/bash" | awk '{FS=":"} {printf $1 "\n"}'
root:x:0:0:root:/root:/bin/bash
user1
user2

說明:FS指定分隔符是一個單獨的動作,而打印輸出是另外一個動作。

看到上面的結(jié)果我們會發(fā)現(xiàn),user1user2用戶的信息正確提取了,而第一行root用戶的信息,是把整行的數(shù)據(jù)都打印輸出了,沒有按:冒號做為分隔符來正確的提取。

是因為awk先把一行數(shù)據(jù)讀取進awk中,然后在用后面的動作,再對讀入的數(shù)據(jù)進行處理。

也就是說我已經(jīng)把第一行的root用戶的信息,已經(jīng)讀入到awk中,$0、$1、$2等變量已經(jīng)賦值好了,然后才在后邊的動作中看到你指定了:冒號作為分隔符,這個時候第一行數(shù)據(jù)已經(jīng)來不及處理了,只能用awk默認(rèn)的處理方式,用空格作為分隔符來處理,這一行沒有空格,就會把這一行的所有數(shù)據(jù)全部打印出來了。

到了處理第二行數(shù)據(jù)的時候,awk已經(jīng)知道要用:冒號作為分隔符,這個時候就可以正確處理數(shù)據(jù)了。

現(xiàn)在就需要用的BEGIN來處理這個問題,把分隔符的指定{FS=":"}放入BEGIN中就可以了。

[root@localhost tmp]# cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN{FS=":"} {printf $1 "\n"}'
root
user1
user2

這樣就可以正確提取到我們需要的數(shù)據(jù)了。

所以在使用awk的時候,如果需要手動指定分隔符,要把這個指定分隔符的動作寫在BEGIN中。

總結(jié):如果有明顯的分隔符,推薦優(yōu)先使用cut命令,因為簡單。

但是如果需要一些判斷的話,比如我需要根據(jù)用戶ID,查看某一個用戶的用戶名。

這個時候用awk就方便很多,cut命令就不能直接處理了,需要寫腳本程序進行過濾。

比如打印uid=500的用戶的用戶名,命令如下:

[root@localhost tmp]# cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN{FS=":"} $3=="500" {printf $1 "\n"}'
user1

# $3=="500"也可以寫成$3==500或者$3=/500/都可以

(3)NF和NR練習(xí)

我們還是以/etc/passwd文件中的內(nèi)容為例,需求打印輸出可登錄的用戶的用戶名,用戶ID,行號,字段數(shù)(也就是列數(shù))。

執(zhí)行如下命令:

# 提示:寫法是,輸出格式在雙引號里,變量在雙引號外。
[root@192 tmp]# cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN{FS=":"} {printf $1 "\t" $3 "\t 行號:" NR "\t 字段數(shù):" NF "\n"}'
root    0    行號:1    字段數(shù):7
user1   500  行號:2    字段數(shù):7
user2   501  行號:3    字段數(shù):7

注意一下,最終傳入awk中處理的數(shù)據(jù)就三行,如下:

[root@192 tmp]# cat /etc/passwd | grep "/bin/bash" 
root:x:0:0:root:/root:/bin/bash
user1:x:500:500::/home/user1:/bin/bash
user2:x:501:501::/home/user2:/bin/bash

3、總結(jié):

我們就學(xué)會前5個awk內(nèi)置變量就可以了,后邊的awk內(nèi)置變量一般用不到,換句話說就是能用Shell處理的,就少用awk處理,以后如果真要用到awk進行更深層次的編程,自己再單獨的學(xué)習(xí)一下awk。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容