awk文法及示例
- 1.awk标準文法格式
- 2.awk變量
- 3.awk數組
- 4.awk循環
- 5.awk函數
- 6.常見示例:
1.awk标準文法格式
awk其名稱得自于它的創始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母。在比較複雜的shell腳本中經常用到,awk grep sed三個合起來,被俗稱為shell三劍客。它是linux系統很強大的文本處理指令,并且友善生成各種報表,文法借鑒了C語言。awk同樣支援處理檔案和标準輸入的内容。
awk最完整的書寫格式如下:
awk 'BEGING{command1}{command2}END{command3}' file_name
其中BEGING和END不是必須的,這裡保留了。
awk簡化版的格式如下:
awk '{command2}' file_name
其中BEGING和END不是必須的,這裡省略了。.
一個簡單完整的例子
[[email protected] awk]# awk 'BEGIN{print"star"}{print $1}END{print "end"}' ips
star
10.100.12.11
10.100.12.12
10.100.12.89
10.100.12.9
10.100.13.8
10.100.12.11
end
[[email protected] awk]#
BEGIN在腳本運作前執行一次,逐行讀入檔案的第1列并列印出來,END在腳本運作後執行一次,
一個簡化版的例子
[[email protected] awk]# awk '{print $1}' ips
10.100.12.11
10.100.12.12
10.100.12.89
10.100.12.9
10.100.13.8
10.100.12.11
[[email protected] awk]#
逐行讀入檔案的第1列并列印出來。
如果要一次在一行列印多個變量,使用逗号
[[email protected] awk]# awk '{print $1,"hello","world"}' ips
10.100.12.11 hello world
10.100.12.12 hello world
10.100.12.89 hello world
10.100.12.9 hello world
10.100.13.8 hello world
10.100.12.11 hello world
[[email protected] awk]#
awk會自動用空格分隔不同的變量。
如果要一次執行多個指令,并且不在一行顯示,使用分号
[[email protected] awk]# awk '{print $1;print "hello";print "world"}' ips
10.100.12.11
hello
world
10.100.12.12
hello
world
10.100.12.89
hello
world
10.100.12.9
hello
world
10.100.13.8
hello
world
10.100.12.11
hello
world
[[email protected] awk]#
每次讀入一行後,三條指令執行一遍。
2.awk變量
awk也是一門功能完整的程式設計語言,是以在各種unix類系統都自帶它。awk的變量主要分為内置變量和自定義變量。
以下是常見的内置變量:
$0 目前記錄(作為單個變量)
$1~$n 目前記錄的第n個字段,字段間由FS分隔
FS 輸入字段分隔符 預設是空格
NF 目前記錄中的字段個數,就是有多少列
NR 已經讀出的記錄數,就是行号,從1開始
RS 輸入的記錄他隔符默 認為換行符
OFS 輸出字段分隔符 預設也是空格
ORS 輸出的記錄分隔符,預設為換行符
ARGC 指令行參數個數
ARGV 指令行參數數組
FILENAME 目前輸入檔案的名字
IGNORECASE 如果為真,則進行忽略大小寫的比對
ARGIND 目前被處理檔案的ARGV标志符
CONVFMT 數字轉換格式 %.6g
ENVIRON UNIX環境變量
ERRNO UNIX系統錯誤消息
FIELDWIDTHS 輸入字段寬度的空白分隔字元串
FNR 目前記錄數
OFMT 數字的輸出格式 %.6g
RSTART 被比對函數比對的字元串首
RLENGTH 被比對函數比對的字元串長度
SUBSEP \034
自定義變量的使用:
awk像python一樣,變量可以不用定義直接使用。
[[email protected] awk]# awk '{print $1;a=NR;print a}' ips
10.100.12.11
1
10.100.12.12
2
10.100.12.89
3
10.100.12.9
4
10.100.13.8
5
10.100.12.11
6
這裡把内置變量NR的值賦給了a,并且再列印a,這裡隻說明如何定義和使用變量。
[[email protected] awk]# awk 'BEGIN{name="robin"}{print $1;a++}END{print a,name}' ips
10.100.12.11
10.100.12.12
10.100.12.89
10.100.12.9
10.100.13.8
10.100.12.11
6 robin
[[email protected] awk]#
經過這個測試我們發現,前面定義的變量name和中間定義的變量a,在END部分都可用直接引用。
3.awk數組
假設現在有一個需求,我們拿到了好多IP位址,想快速計算出出現次數前3的IP位址。
使用awk的數組實作
[[email protected] awk]# awk '{ip[$1]++}END{for(i in ip)print(i,ip[i])}' ips|sort|head -n 3
10.100.12.11 2
10.100.12.12 1
10.100.12.89 1
[[email protected] awk]#
使用awk、sort、uniq實作
[[email protected] awk]# awk '{print $1}' ips|sort|uniq -c|head -n 3
2 10.100.12.11
1 10.100.12.12
1 10.100.12.89
[[email protected] awk]#
4.awk循環
待續
5.awk函數
待續
6.常見示例:
example1 分列顯示文本檔案内容, $0所有列,$1第一列,$2第二列
[[email protected] linux-shell-test]# awk '{ print $0 }' awk.sh
hello robin
nihao huanhuan
byby joe
[[email protected] linux-shell-test]# awk '{ print $1 }' awk.sh
hello
nihao
byby
[[email protected] linux-shell-test]# awk '{ print $2 }' awk.sh
robin
huanhuan
joe
example2 分列顯示标準輸入文本
[[email protected] linux-shell-test]# ps -ef|grep python|awk '{ print $0 }'
root 803 1 0 Feb28 ? 00:00:43 /usr/bin/python -Es /usr/sbin/tuned -l -P
root 6820 6216 0 23:21 pts/0 00:00:00 grep --color=auto python
root 19785 1 0 Feb29 ? 00:00:50 python proxyserver.py 11081
[[email protected] linux-shell-test]# ps -ef|grep python|awk '{ print $2 }'
803
6828
19785
example3 使用自定義分隔符分列顯示文本,-F ‘=’
[[email protected] linux-shell-test]# awk -F '=' '{print $0 }' awk.sh
hello robin
nihao huanhuan
byby joe
name1=robin
name2=joe
age1=22
[[email protected] linux-shell-test]# awk -F '=' '{print $1 }' awk.sh
hello robin
nihao huanhuan
byby joe
name1
name2
age1
[[email protected] linux-shell-test]# awk -F '=' '{print $2 }' awk.sh
robin
joe
22
example4 分列後顯示前N行,NR<=3
[[email protected] linux-shell-test]# awk 'NR<=3 { print $2 }' awk.sh
robin
huanhuan
joe
example5 讀取shell中變量,用于awk指令參數
[[email protected] linux-shell-test]# awk -v var=$split_char -F '=' 'NR<=6 { print $1 var }' awk.sh
hello robin=
nihao huanhuan=
byby joe=
name1=
name2=
age1=
example6 拆分标準輸入或者檔案内容,并重新格式化
[[email protected] linux-shell-test]# echo -e 'line1=hello\nline2=world'|awk -F '=' '{ print $1": "$2 }'
line1: hello
line2: world
[[email protected] linux-shell-test]# awk -F '=' 'NR>3 { print $1": "$2 }' awk.sh
name1: robin
name2: joe
age1: 22
example7 awk也算是一個程式設計語言,我們先把簡單的、最常用的使用方式搞清除了,再來嘗試進階的使用。
請打開後自行學習 https://awk.readthedocs.io/en/latest/index.html