前言
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