技能篇:awk教程-linux命令

潛行前行發表於2021-06-12

前言

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工作流程

image.png

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

歡迎指正文中錯誤

參考文章

相關文章