Awk簡介
Awk是一種編程語言,誕生於1977年,其名稱爲三位作者姓的首字母縮寫:
Alfred Aho 、Peter Weinberger 和 Brian Kernighan
awk主要用於linux/unix下對文本和數據進行掃描處理
數據可以來自標準輸入,文件,管道
awk有衆多的發行版本,awk,nawk,gawk,MKS awk,tawk包括開源產品和商業產品
目前linux中常用的swk編譯器版本mawk,gawk
rhel系統默認的爲gawk
ubuntu系列產品用mawk
此文章用gawk實現,GUN開源項目awk解釋器的開源代碼實現
Awk工作流程
首先對文件逐行掃描,從第一行到最後一行,逐行進行匹配特定模式的行,並在這些行上進行用戶想要的操作,
Awk基本結構由模式匹配和處理過程(處理動作)組成
pattern {action}
注意:awk讀取文件每一行時,將對該行與給定的模式相匹配,如果匹配,則處理執行處理過程,否則不做任何操作,
如果沒有指定處理腳本,則把匹配的行標準輸出,默認處理動作爲print打印
如果沒有指定模式匹配,則默認匹配所有數據
Awk有倆個特殊模式,BEGIN/END,被放置在沒有讀取任何數據之前以及在所有數據讀取完成後執行
Awk的基礎語法
格式:
gawk [選項] -f program-file [--] file
#選項:
-F fs, --field-separator fs
指定fs爲輸入行的分隔符(默認的分隔符爲空格或製表符)
-v var=val,--assign var=val
在執行處理動作之前,設置一個變量var值爲var
-f program-file,--file program-file
從腳本文件中讀取awk指令,以取代在命令參數中輸入腳本
-W compat,-W traditional,--compat,--traditional
使用兼容模式運行AWK,GUN拓展選項將被忽略
-W dump-variables[=file] ,--dump-variables[=file]
打印全局變量(變量名,類型,值)到文件中,
如果沒有提供文件名,則自動輸出至名爲dump-variables文件中(演示失敗)
-W copyleft ,-W copyright,--copyleft,--copyright
輸出打印簡短的GUN版本信息
- awk程序語法結構:一個awk程序包含一系列的模式{動作指令}或者函數定義
- 模式可以是BEGIN/END/表達式用來限定操作對象的多個表達式使用逗號隔開
- 動作指令需要用{}引起來
案例
1。使用正則表達式匹配空行: /^$/,動作爲打印"哈哈哈哈,有空行"
[root@localhost ~]# awk '/^$/ {print "哈哈哈哈,有空行"}' quote.txt
哈哈哈哈,有空行
哈哈哈哈,有空行
哈哈哈哈,有空行
哈哈哈哈,有空行
[root@localhost ~]#
2.匹配包含anconda的行,並打印 /etc/syconfig/network
[root@#localhost ~]# awk '/anaconda/' /etc/sysconfig/network
# Created by anaconda
[root@#localhost ~]#
3.利用腳本文件,判斷是否有空行
[root@#localhost ~]# cat awk1.sh
/^$/ {print "哈哈哈哈哈哈哈啊哈哈啊"}
[root@#localhost ~]#
[root@#localhost ~]# awk -f awk1.sh quote.txt
哈哈哈哈哈哈哈啊哈哈啊
哈哈哈哈哈哈哈啊哈哈啊
哈哈哈哈哈哈哈啊哈哈啊
哈哈哈哈哈哈哈啊哈哈啊
[root@#localhost ~]#
awk操作指令
1.記錄與字段
Awk一次從文件中讀取一條記錄,並將記錄存儲在字段變量$0中,記錄被分割爲字段並存儲在$1,$2,$3………………$NF中(分隔符默認爲空格或製表符)
'NF:內建變量,記錄的字段個數'
#輸出一段話並輸出第一個字段,第二個字段,第三個字段
[root@#localhost ~]# echo I love my gril friend | awk '{print $1,$2,$3}'
I love my
[root@#localhost ~]# echo I love my gril friend | awk '{print $1,$2,$3,$5,$4}'
I love my friend gril
[root@#localhost ~]#
#讀取輸入行數並輸出該行
[root@#localhost ~]# echo hello world | awk '{print $0,$NF}'
hello world world
[root@#localhost ~]# echo hahahhahaha | awk -F"a" '{print $NF}'
[root@#localhost ~]# echo hahahhahaha | awk -F"h" '{print $NF}'
a
[root@#localhost ~]#
2.字段與分隔符
默認awk讀取數據以空格或製表符作爲分隔符
但可以通過-F來改變分隔符
[root@#localhost ~]# awk -F: '{print $1}' /etc/passwd
[root@#localhost ~]# awk 'BEGIN {FS=":"} {print $1}' /etc/passwd
#指定多個分割符
[root@#localhost ~]# echo 'hello the:world,!' | awk 'BEGIN {FS="[:,]"} {print $1,$2,$3,$4}'
hello the world !
[root@#localhost ~]#
3.內置變量
變量名稱 描述
ARGC 命令行參數個數 -v
FILENAME 當前輸入文檔的名稱
FNR 當前輸入文檔的記錄編號,多個輸入文檔時有用
'NR 輸入流當前記錄編號'
'NF 當前記錄的字段個數'
FS 字段分隔符
OFS 輸出--字段--分隔符,默認是空格
ORS 輸出--記錄--分隔符,默認換行符 \n
RS 輸入記錄分隔符,默認換行符
#示例文件
[root@#localhost ~]# cat test1.txt
This is a test file
Welcome to Jacob's Class
[root@#localhost ~]# cat test2.txt
Hello the world
Wow! I'm overwhelmed.
Ask for more
[root@#localhost ~]#
#輸出當前文檔的當前行編號,第一個文件倆行,第二個文件三行
[root@#localhost ~]# awk '{print FNR}' test1.txt test2.txt
#Awk將倆個文檔作爲一個整體的輸入流,通過NR輸入當前編號
[root@#localhost ~]# awk '{print NR}' test1.txt test2.txt
[root@#localhost ~]# awk '{print $1,$2,$3,$4}' test1.txt
This is a test
Welcome to Jacob's Class'
[root@#localhost ~]#
#通過OFS將輸出分割符設置爲'-',print在輸出時第1,2,3個字段中間的分割符爲‘-’
[root@#localhost ~]# awk 'BEGIN {OFS="-"} {print $1,$2,$3,$4}' test1.txt
This-is-a-test
Welcome-to-Jacob's-Class
[root@#localhost ~]#
#示例文件
[root@#localhost ~]# cat test3.txt
mail from:[email protected]
subjectLhello
data:2018-11-12 17:00
content:Hello,The world
mail from: [email protected]
subject:congregation
data:2018-11-12 08:31
content:Congregation to you.
mail from: [email protected]
subject:Test
data:2018-11-12 10:20
content:This is a test mail
[root@#localhost ~]#
#讀取輸入數據,以空白行爲記錄分割符,即第一個空白行前的內容爲一個記錄
[root@#localhost ~]# awk 'BEGIN {FS="\n";RS=""} {print $2}' test3.txt
subjectLhello
subject:congregation
subject:Test
[root@#localhost ~]#
4.表達式與操作
表達式由變量,常量,函數,正則表達式,操作符組成
awk中變量有字符和數字變量,如果在awk中定義變量沒有初始化,則初始化值爲空字符或0
字符操作一定加引號
#定義變量
a='hello'
b=12
#操作符
+
-
*
/ 除
% 取餘
^ 冪運算
++
--
+=
-=
*=
/=
>
<
>=
<=
== 等於
!= 不等於
~ 匹配
!~ 不匹配
&& 與
|| 或
#案例
[root@#localhost ~]# echo test | awk 'x=2 {print x+3}'
[root@#localhost ~]# echo hello | awk 'x=1,y=3 {print x*2,y*3}'
2 9
[root@#localhost ~]#
#統計所有空白行
[root@#localhost ~]# awk '/^$/ {print x+=1}' test3.txt
1
2
[root@#localhost ~]# awk '/^$/ {x+=1} END {print x}' test3.txt
2
[root@#localhost ~]#
#打印root用戶的UID號
[root@#localhost ~]# awk -F: '$1~/root/ {print $3}' /etc/passwd
0
#打印用戶uid號大於500的用戶
[root@#localhost ~]# awk -F: '$3>500 {print $1}' /etc/passwd
polkitd
unbound
colord
saslauth
libstoragemgmt
nfsnobody
chrony
gnome-initial-setup
hello
[root@#localhost ~]#