2021-05-12 14:32:11
Linux系統之文字格式化工具awk
一、文字處理工具
grep、sed和awk都是文字處理工具,雖然都是文字處理工具但卻都有各自的優缺點,一種文字處理命令是不能被另一個完全替換的,否則也不會出現三個文字處理命令了。只不過,相比較而言,sed和awk功能更強大而已,且已獨立成一種語言來介紹。
awk:報告生成器,格式化以後顯示。如果對處理的資料需要生成報告之類的資訊,或者你處理的資料是按列進行處理的,最好使用awk。
二、awk可以完成的一些功能
-
將文字檔案看做由記錄和欄位組成的文字資料庫
-
使用變數運算元據庫
-
使用算術和字串操作符
-
使用普通的程式設計結構,例如迴圈和條件
-
生幫格式化報告
-
定義函數
-
從指令碼中執行unix命令
-
處理unix命令的結果
-
更加巧妙的處理命令列的引數
-
更容易地處理多個輸入流
三、語法格式
1
2
|
# awk [options] 'script' file1 file2, ... # awk [options] 'PATTERN { action }' file1 file2, .. |
1、選項
-F fs or --field-separator fs:
指定輸入檔案折分隔符,fs是一個字串或者是一個正規表示式,如-F:
1
2
3
4
|
#awk -F: '/root/{print $1,$NF}' /etc/passwd #awk -F: '/root/{print $1$NF}' /etc/passwd #awk -F: '/root/{print $1 $NF}' /etc/passwd #awk -F: '/root/{print $1"#"$NF}' /etc/passwd |
-v 選項定義的變數在指令碼執行之前即存在,可以在指令碼的 BEGIN 流程中被呼叫;
2、awk的輸出:print和printf
⑴、print的使用格式:
print item1, item2, ...
要點:
①、各專案之間使用逗號隔開,而輸出時則以空白字元分隔;
②、輸出的item可以為字串或數值、當前記錄的欄位(如$1)、變數或awk的表示式;數值會先轉換為字串,而後再輸出;
③、print命令後面的item可以省略,此時其功能相當於print $0, 因此,如果想輸出空白行,則需要使用print "";
注意,在AWK中,$表示欄位,使用者變數不需要加$,這是AWK與shell或者Perl不同之處!在shell中,變數定義時不加$,再次參照時則需要用$,而在Perl中,無論定義和參照時都需要加$ (Perl中$表示標量,另有@和%符號表示陣列和Hash變數)。
範例
⑵、printf的使用格式
printf format, item1, item2, ...
format格式的指示符都以%開頭,後跟一個字元,
%c
轉換數位成ASCII,如printf "%c", 67結果為C。
%d, %i
列印十進位制整數,如printf "%dn", 6.745結果為6。
%e, %E
轉換數位為科學(指數)符號,如printf "%4.3en", 6745結果為6.745e+03。
%f
以浮點表示法列印數位,如 printf "%4.3fn", 6745結果為6745.0000000
%s
列印字串,如printf "%10sn", 6745結果為十個空格加6745。
可更改的格式:
N$
位置指示符,可調整字串的輸出位置。printf "%s %s %sn", "I", "lOVE","YOU"輸出為:I LOVE YOU,我們調整一下位置,printf "%3$s %2$s %1$sn", "YOU", "LOVE","I",輸出結果為:I LOVE YOU
修飾符
N: 顯示寬度;
3、模式和操作
⑴、模式可以是以下任意一個:
-
/正規表示式/:使用萬用字元的擴充套件集。
-
關係表示式:可以用下面運算子表中的關係運算子進行操作,可以是字串或數位的比較,如$2>%1選擇第二個欄位比第一個欄位長的行。
-
模式匹配表示式:用運算子~(匹配)和~!(不匹配)。
-
模式,模式:指定一個行的範圍。該語法不能包括BEGIN和END模式。
-
BEGIN:讓使用者指定在第一條輸入記錄被處理之前所發生的動作,通常可在這裡設定全域性變數。
-
END:讓使用者在最後一條輸入記錄被讀取之後發生的動作。
⑵、操作由一人或多個命令、函數、表示式組成,之間由換行符或分號隔開,並位於大括號內。主要有四部份:
-
變數或陣列賦值
-
輸出命令
-
內建函數
-
控制流命令
4、變數
⑴、awk內建變數之記錄變數
FS: field separator | 讀取檔案本時,所使用欄位分隔符 |
RS: Record separator | 輸入文字資訊所使用的換行符 |
OFS: Output Filed Separator | 輸出欄位分隔符(預設值是一個空格) |
ORS:Output Row Separator | 輸出記錄分隔符(預設值是一個換行符) |
註:
從$1,$2一直到$NF,整行用$0標,如果$0被賦予新值,所有的$1,$2...和NF都將被重新計算。同樣,若$i被改變,$0將用OFS重新計算。
⑵、awk內建變數之資料變數
NR: The number of input records | awk命令所處理的記錄數;如果有多個檔案,這個數目會把處理的多個檔案中行統一計數 |
NF:Number of Field | 當前記錄的field個數 |
FNR | 當前檔案的相對記錄數 |
ARGV | 陣列,儲存命令列本身這個字串,如awk '{print $0}' a.txt b.txt這個命令中,ARGV[0]儲存awk,ARGV[1]儲存a.txt |
ARGC | awk命令的引數的個數 |
FILENAME | awk命令所處理的檔案的名稱 |
ENVIRON | 當前shell環境變數及其值的關聯陣列 |
NR用法
NF用法(預設以空格分隔)
FNR用法
ARGV用法
之二
FILENAME用法
ENVIRON用法
註:
ARGV陣列由ARGV[0]....ARGV[ARGC-1]組成,第一個元素是0而不是1,這與AWK中的般陣列不同
ENVIROND陣列在shell與AWK的互動中非常有用,使用ENVIRON["PARA_NAME"]來獲取環境變數$PARA_NAME的值,其中引號“”不可少!
5、標準輸出與重定向
⑴、輸出重定向
範例:
1
2
|
# awk -F" " '{printf "%-15s %in",$1,$3 > "/dev/stderr" }' /etc/issue # awk -F" " '{printf "%-15s %in",$1,$3 > "/dev/null" }' /etc/issue |
6、awk的操作符:
x%y:
範例
需要注意的是,如果某模式為=號,此時使用/=/可能會有語法錯誤,應以/[=]/替代;
||
範例:
範例
⑼、函數呼叫:
7、控制語句
語法:
if (condition) {then-body} else {[ else-body ]}
範例:
1
2
3
4
|
#awk '{if ($3==0) {print $1, "Adminitrator";} else { print $1,"Common User"}}' /etc/passwd #awk -F: '{if ($1=="root") print $1, "Admin"; else print $1, "Common User"}' /etc/passwd #awk -F: '{if ($1=="root") printf "%-15s: %sn", $1,"Admin"; else printf "%-15s: %sn", $1, "Common User"}' /etc/passwd #awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd |
⑵、 while
語法:
while (condition){statement1; statment2; ...}
範例:
1
2
3
4
|
#awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd #awk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}' /etc/passwd #awk '{i=1;while (i<=NF) {if ($i>=20000) print $i; i++}}' random.txt #random.txt檔案的內容為一堆亂數。 |
⑶、do-while 至少執行一次迴圈體,不管條件滿足與否
語法:
do {statement1, statement2, ...} while (condition)
範例:
1
2
3
4
5
6
7
8
|
#awk 'BEGIN{ sum =0; i=0; do { sum +=i; i++; } while (i<=100) print sum ;}' |
⑷、for
範例:
1
|
#awk -F: '{for(i=1;i<=3;i++) { if (length($i)>=8) {print $i}}}' /etc/passwd |
for迴圈還可以用來遍歷陣列元素:
語法:
for (i in array) {statement1, statement2, ...}
範例:
1
|
#awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%-15s:%in",A,BASH[A]}}' /etc/passwd |
⑸、 case
範例:
1
|
# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd |
9、awk中使用陣列
語法
for (var in array) { statement1, ... }
1
|
#netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' |
1
2
3
|
# netstat -ant | awk '/:80>/{split($5,clients,":");IP[clients[1]]++}END{for(i in IP){print IP[i],i}}' | sort -rn | head -50 # netstat -tan | awk '/:80>/{split($5,clients,":");ip[clients[4]]++}END{for(a in ip) print ip[a],a}' | sort -rn | head -50 # df -lh | awk '!/^File/{split($5,percent,"%");if(percent[1]>=20){print $1}}' |
length([string])
功能:取string字串中的子串,從start開始,取length個;start從1開始計數;
1
|
# tail -10 /etc/passwd |awk -F: '{print substr($1,1,6)}' |
system(command)
功能:執行系統command並將結果返回至awk命令
1
|
# awk 'BEGIN{print system("ls -l")}' |
功能:systime函數返回從1970年1月1日開始到當前時間(不計閏年)的整秒數
1
|
# awk 'BEGIN{s="acl";print toupper(s)}' |
================================完===================================================
PS:
awk簡單應用到此結束!
AWK簡介及使用範例 http://www.linuxidc.com/Linux/2013-12/93519.htm
AWK 簡介和例子 http://www.linuxidc.com/Linux/2012-12/75441.htm
Shell指令碼之AWK文字編輯器語法 http://www.linuxidc.com/Linux/2013-11/92787.htm
正規表示式中AWK的學習和使用 http://www.linuxidc.com/Linux/2013-10/91892.htm
文字資料處理之AWK 圖解 http://www.linuxidc.com/Linux/2013-09/89589.htm
如何在Linux中使用awk命令 http://www.linuxidc.com/Linux/2014-10/107542.htm
文字分析工具-awk http://www.linuxidc.com/Linux/2014-12/110939.htm
本文永久更新連結地址:http://www.linuxidc.com/Linux/2016-02/128150.htm
相關文章