AWK是一門處理文本文件的語言。它把文件看作一串記錄(record),缺省情況下一行即爲一個記錄。每一行又被拆成若干域(field)。我們可以把一行中的第一個詞看作第一域,第二個詞看作第二域,以此類推
AWK 在1977年被Alfred Aho, Peter Weinberger, and Brian Kernighan開發出來, 和大部分語言一樣,AWK是應實際需要而生的。上世紀80年代初,Alfred Aho還是貝爾實驗室的研究員。那時需要追蹤經費預算。同時因爲Alfred Aho在臨近的一所大學兼職,追蹤學生的成績也成了一件棘手的事情。
Alfred Aho想要一種小巧的語言,能只寫一兩行代碼就完成這些工作。碰巧Brian Kernighan也有這種需求,於是他們倆一起開發了一個專門針對簡易數據處理的模式匹配語言。
GREP對他們的影響很大,它是UNIX下一個很流行的字串匹配工具。GREP也是他們研究中心開發的。GREP可以根據某個正則表達式查找文本文件中特定的行,然後輸出它們。
他們想進一步擴展它,使得數字也能向字串那樣處理。我們還想在打印之外提供一些計算功能。
開發AWK僅僅是用來滿足他們,或是那些對計算機不是很懂的人,處理常規數據的需要。它採取“匹配模式——執行動作”的方式工作
語法形式
awk pattern { action }
awk [ -F fs ] [ -v var=value ] [ 'prog' | -f progfile ] [ file ... ]
上面的語法的意思是根據模式匹配或者調用參數,然後進行你想進行的操作,還是過會來幾個例子比較直觀點。
參數
-F fs fs指定輸入分隔符,fs可以是字符串或正則表達式,如-F:
-v var=value 賦值一個用戶定義變量,將外部變量傳遞給awk
-f scripfile 從腳本文件中讀取awk命令
AWK內置變量
CONVFMT 數字轉換格式(默認值爲%.6g)。
FNR 同NR,但相對於當前文件。
NF 表示字段數,在執行過程中對應於當前的字段數。
NR 表示記錄數,在執行過程中對應於當前的行號。
OFMT 數字的輸出格式(默認值是%.6g)。
OFS 輸出字段分隔符(默認值是一個空格)。
ORS 輸出記錄分隔符(默認值是一個換行符)。
RS 記錄分隔符(默認是一個換行符)。
實例演示
☁ ~ awk "BEGIN { print \"Hello AWK\"}"
Hello AWK
☁ ~ awk 'BEGIN { print "Hello AWK"}'
Hello AWK
☁ ~ awk "BEGIN { print "Hello AWK"}"
awk: syntax error at source line 1
context is
>>> <<<
awk: illegal statement at source line 1
missing }
上面這樣的情況是不行的,因爲多個引號會讓編譯器分不清楚主次關係,所以必須加\。
PS: 網上說明shell會對""的參數進行解析,''會比較原汁原味。
個人理解就是""裏面如果是變量的話,這個變量會被當成字符串輸出。通過下面這個例子實現的。($代表取第幾個域,1代表第一列,0代表所有)
☁ ~ echo test|awk '{print $1}'
test
☁ ~ echo test|awk '{print "$1"}'
$1
☁ ~
這次試着使用網上的一些例子,用vi編輯器保存一個文件,並且對這個文件進行搜索等操作。因爲支持正則表達式,所以調用上面的格式就能完成這個搜索過程。
☁ Documents cat mail-list
Amelia 555-5553 amelia.zodiacusque@gmail.com F
Anthony 555-3412 anthony.asserturo@hotmail.com A
Becky 555-7685 becky.algebrarum@gmail.com A
Bill 555-1675 bill.drowning@hotmail.com A
Broderick 555-0542 broderick.aliquotiens@yahoo.com R
Camilla 555-2912 camilla.infusarum@skynet.be R
Fabius 555-1234 fabius.undevicesimus@ucb.edu F
Julie 555-6699 julie.perscrutabor@skeeve.com F
Martin 555-6480 martin.codicibus@hotmail.com A
Samuel 555-3430 samuel.lanceolis@shu.edu A
Jean-Paul 555-2127 jeanpaul.campanorum@nyu.edu R
☁ Documents awk -F "" '{print $1}' mail-list
awk: field separator FS is empty
Amelia
Anthony
Becky
Bill
Broderick
Camilla
Fabius
Julie
Martin
Samuel
Jean-Paul
☁ Documents awk -F "" '/li/ {print $0}' mail-list
awk: field separator FS is empty
Amelia 555-5553 amelia.zodiacusque@gmail.com F
Broderick 555-0542 broderick.aliquotiens@yahoo.com R
Julie 555-6699 julie.perscrutabor@skeeve.com F
Samuel 555-3430 samuel.lanceolis@shu.edu A
上面的一些應該是最基本的使用方法了. 接下來是對awk的內置函數等參數的使用.
語法格式差不多是這個樣子:
awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file
第一步:執行BEGIN{ commands }語句塊中的語句;
第二步:逐行掃描文件,從第一行到最後一行重複這個過程,直到文件全部被讀取完畢。
第三步:當讀至輸入流末尾時,執行END{ commands }語句塊。
來計算有多少行可以通過如下命令:
☁ Documents awk 'BEGIN{} { count++ } END{ print count }' mail-list
11
☁ Documents wc -l mail-list
11 mail-list
☁ Documents awk '{ count++ } { print count }' mail-list
1
2
3
4
5
6
7
8
9
10
11
☁ Documents awk 'NR%2==1{next}{print NR,$0}' mail-list
2 Anthony 555-3412 [email protected] A
4 Bill 555-1675 [email protected] A
6 Camilla 555-2912 [email protected] R
8 Julie 555-6699 [email protected] F
10 Samuel 555-3430 [email protected] A
☁ Documents awk '{count++;}{if(count==1) print NR,$1}' mail-list
1 Amelia
☁ Documents awk 'BEGIN{count=0}{while(count<5){ count++;print NR,$1;next }}' mail-list
1 Amelia
2 Anthony
3 Becky
4 Bill
5 Broderick
這條語句如果去掉BEGIN的話就代表每執行一次 count都會被初始化成0。
根據理解, BEGIN是放置一些初始參數的地方, 而且只執行一次, END也只執行一次。
NR 表示記錄數. 也是可以通過count來算出第幾行, 來選取出你想要的行數或者匹配某一種正則的情況的數據。
代碼寫的不太規範, 如果想要寫一份漂亮規範的awk代碼的話最好去網上或者github上面找一些大牛們的腳本。
以上應該是比較簡單的AWK的應用了, 貼上一些參考的網站的鏈接,感覺挺有用的。
Linux The GNU Awk User’s Guide
Linux AWK WIKI
Linux AWK
Linux AWK Leetcode 可以用來練手。