前言
AWK是一門解釋型的編程語言。用於文本處理,它的名字來源於它的三位作者的姓氏:Alfred Aho, Peter Weinberger 和 Brian Kernighan
- awk 程序結構
- 運行awk文件腳本
- awk基礎語法
- awk 程序常用的內建變量
關注公眾號,一起交流,微信搜一搜: 潛行前行
程序結構
awk命令模式:
awk ' BEGIN {awk-commands} /pattern/ {awk-commands} END {awk-commands}' fileName
- 若存在匹配模式pattern,則需要用 / 包含
- awk-commands 程序代碼塊必須被大括號
- BEGIN語句塊
BEGIN {awk-commands}
,可選,它只執行一次,在這里可以初始化變量。BEGIN是AWK的關鍵字,必須為大寫 - BODY 語句塊
/pattern/ {awk-commands}
,BODY語句塊中的命令會對輸入的每一行執行,可以通過提供模式來控制這種行為 - END 語句塊
END {awk-commands}
,可選,END語句塊在程序的最后執行,END是AWK的關鍵字,必須為大寫
awk工作流程
BODY語句塊執行解析
腳本命令: awk '{ [代碼語句1][代碼語句2] }
;如果沒有 fileName 或其他輸入流,且存在BODY語句塊,BODY語句塊會進入死循環;代碼語句表達式以分號結束,也可以用換行符結束
- 1: 讀入一行數據,並這一行的數據填入 $0;每一列的數據分別填入 $1, $2.... 等變量當中
- 2: 執行 代碼語句
- 3: 若還有后續的行數據,則重復上面 1~2 的步驟,直到每一數據都讀完為止
運行awk文件腳本
- awk文件腳本以awk后綴結尾
- 選項 [-f]:
awk -f command.awk marks.txt
awk基礎語法
- awk變量不需要提前定義,也不許要指定類型
awk 'BEGIN{sum=1;print sum}'
1
- 流程控制
#-------- 偽代碼 1 ---------
if ({condition})
代碼邏輯...
else if({condition})
代碼邏輯...
else
代碼邏輯...
#-------- 偽代碼 2 ---------
for ({初始化}; {condition};{后續邏輯}){
代碼邏輯...
}
#-------- 偽代碼 3 ---------
while ({condition}){
代碼邏輯...
}
#-------- 偽代碼 4 ---------
do{
代碼邏輯...
}while ({condition})
- 運算符,基本和 java 編程語言一樣 下面簡單列舉幾個運算符
符號 | 說明 | 示例 |
---|---|---|
^ | 指數操作符 | a = a ^ 2 |
-/+ | 一元操作符 | a = -10; a = +a; |
condition ? action : action | 三元操作符 | (a > b) ? max = a : max = b; |
&& / || | 邏輯操作符 | if (num >= 0 && num <= 7) |
== / != | 等於不等於 | if (a == b) |
awk 'BEGIN{sum=1;sum++; if(sum==2) print sum}'
2
- 數組,AWK支持關聯數組,也就是說,不僅可以使用數字索引的數組,還可以使用字符串作為索引;刪除數組元素使用delete語句
delete arr[0]
$ awk 'BEGIN {arr["lwl"] = 1; arr["csc"] = 2; for (i in arr) printf "arr[%s] = %d\n", i, arr[i]}'
arr[lwl] = 1
arr[csc] = 2
- 字符串操作
---- 空格拼接字符,則默認使用逗哈作為拼接符 ----
awk 'BEGIN { str1 = "csc, "; str2 = "lwl"; str3 = str1 str2; print str3 }'
csc, lwl
- 字符串相關的內建函數
index(str, sub) #獲取sub在str起始索引
length(str) #獲取str長度
match(str, regex) #str是否匹配regex模式
split(str, arr, regex)
sub(regex, sub, string)
substr(str, start, l)
tolower(str)
toupper(str)
正則表達式
- 匹配符:~ 和 !~ 分別代表匹配和不匹配
$ awk '$0 !~ 9' marks.txt
1) Amit Physics 80
3) Shyam Biology 87
- 匹配符和正則表達式
# log.txt內容文件
1 csc world
2 lwl hello
----------輸出第二列包含lwl的行------------------------------
$ awk '$2 ~ /lwl/ {print $2,$3}' log.txt
lwl hello
------輸出包含csc的行---------------------------
$ awk '/csc/ {print $0}' log.txt
1 csc world
awk 程序常用的內建變量
變量 | 描述 |
---|---|
$n | 當前記錄的第n個字段,字段間由FS分隔 |
$0 | 完整的輸入記錄 |
ARGC | 命令行參數的數目 |
ARGV | 包含命令行參數的數組 |
ENVIRON | 環境變量 |
ERRNO | 最后一個系統錯誤的描述 |
FILENAME | 當前文件名 |
FS | 字段分隔符(默認是任何空格) |
IGNORECASE | 進行忽略大小寫的匹配 |
NF | 一條記錄的字段的數目 |
NR | 已經讀出的記錄數,就是行號,從1開始 |
FNR | 和NR類似,不過如果存在多個輸入文件,FNR當前文件的行號 |
OFS | 輸出 字段分隔符 |
ORS | 輸出 行分隔符 |
RLENGTH | 由match函數所匹配的字符串的長度 |
RS | 記錄分隔符(默認是一個換行符) |
RSTART | 由match函數所匹配的字符串的第一個位置 |
ARGIND | 循環處理數據時,當前被處理的ARGV的索引 |
PROCINFO | 包含進程信息的關聯數組,例如UID,進程ID等 |
- ARGV 命令行參數個數
$ awk 'BEGIN {
for (i = 0; i < ARGC - 1; ++i) {
printf "ARGV[%d] = %s\n", i, ARGV[i]
}
}' csc lwl
ARGV[0] = csc
ARGV[1] = lwl
- ENVIRON 環境變量
$ awk 'BEGIN { print ENVIRON["USER"] }'
csc
- FILENAME 當前文件名
$ awk 'END {print FILENAME}' test.txt
test.txt
- RSTART,由match函數所匹配的字符串的第一個位置
$ awk 'BEGIN { if (match("One Two Three", "Thre")) { print RSTART } }
9