awk的常用語法及示例
awk的使用方法
簡介
awk是一種優良的文字處理器,它可以掃描檔案中的每一行,查詢與命令列中所給定內容相匹配的模式。如果發現匹配內容,則進行下一個程式設計步驟。如果找不到匹配內容,則繼續處理下一行。它也是一種用於處理文字的程式語言工具.也正是因為它的強大功能,所以它也是處理文字所用的三個工具中最複雜的一個.
格式
awk [選項] ‘命令’ 檔案
awk指令碼的組成
awk指令碼是由模式和操作組成的
模式
-
正則表示式:正則表示式用/ /加在中間
-
關係表示式:大於,小於,大於等於,小於等於,等於,不等於
-
模式匹配表示式:用 ~ 表示匹配, !~ 表示不匹配
-
BEGIN語句塊,pattern語句塊,END語句塊
操作 操作由一個或多個命令、函式、表示式組成,之間由換行符或分號隔開,並位於大括號內,主要部分是 :
- 變數或陣列賦值
- 輸出命令
- 內建函式
- 控制流語句
基本結構 awk ‘BEGIN{ print “頭部分”} pattern{ 命令} END{ print “尾部分”}’ 這三部分都是可選的,也就是說可以不出現在指令碼語句中
awk測試
awk的內建變數非常的多,我們直接使用習題來進行測試
1. 如何使用awk輸出 hello awk
awk 'BEGIN{ print "hello awk"}'
使用這種方法awk就相當於我們用的echo
2. 那麼我們在輸出一個符號 ‘ 呢
awk 'BEGIN { print "這是一個符號 ('"'"')" }'
是不是看起來非常複雜,其實拆開看:第一組引號"’'這是引用,然後" "是用來轉義 ’ 的
那麼我們可以在對這段簡化
awk 'BEGIN { print "這是一個符號 ('\'')" }'
在這裡使用轉義符 \ 對上一段的“”進行了替換,很明顯的簡化了程式碼
還可以再使用變數,即-v引數例如
awk -v sq="'" 'BEGIN{print "這是一個符號("sq")"}'
我們在這裡一開始使用-v引數定義了一個名為sq的變數,內容為‘ 在後面的awk語句中就可以直接使用 需要注意的是,每定義一個變數,就需要一個-v引數
擴充套件 \47
表示單引號’
\42
表示雙引號"
3. 使用awk對文字進行處理
在進行測試之前,先準備一個名為mail-list的檔案,內容是
Anthony 555-3412 [email protected] A
Becky 555-7685 [email protected] A
Bill 555-1675 [email protected] A
Broderick 555-0542 [email protected] R
Camilla 555-2912 [email protected] R
Fabius 555-1234 [email protected] F
Julie 555-6699 [email protected] F
Martin 555-6480 [email protected] A
Samuel 555-3430 [email protected] A
Jean-Paul 555-2127 [email protected] R
一個名為data的檔案,內容為
Feb 15 32 24 226
Mar 15 24 34 228
Apr 31 52 63 420
May 16 34 29 208
Jun 31 42 75 492
Jul 24 34 67 436
Aug 15 34 47 316
Sep 13 55 37 277
Oct 29 54 68 525
Nov 20 87 82 577
Dec 17 35 61 401
Jan 21 36 64 620
Feb 26 58 80 652
Mar 24 75 70 495
Apr 21 70 74 514
1. 在mail-list中對li進行匹配
awk '/li/ { print $0 }' mail-list
對字串進行匹配需要用/ /包起來; $0 這個變數包含執行過程中當前行的文字內容,簡單來說,就是輸出li所在行的所有內容
2. 匹配data中長度大於80的所有欄位
awk 'length($0) > 80' data
匹配欄位使用length()函式 發現沒有輸出結果,說明沒有匹配到長度大於80的欄位
3. 輸出data中長度最長的行長度
awk '{ if (length($0) > max) max = length($0) }END { print max }' data
在這裡,我們在awk中添加了if語句,去尋找data中最長的欄位長度,最後對其進行輸出
4. 輸出data中長度最短的行的長度
expand data | awk '{ if (x < length($0)) x = length($0) }END { print "maximum line length is " x }'
這裡使用了expand命令,它也是一種檢視檔案的命令,在這裡不多細講
5.列印至少有一個欄位的每一行
awk 'NF > 0' data
NF表示總欄位數 NF > 0 表示欄位數大於零的行
6.列印從0到100的七個隨機數
awk 'BEGIN { for (i = 1; i <= 7; i++)print int(101 * rand()) }'
rand()也是一個函式,它用來生成隨機數,此處用法為: n*rand()生成一個0-n的隨機數,多次呼叫會產生相同的隨機數,所以產生的並不是隨機數,而是偽隨機數
7.在mail-list中匹配12 在data中匹配21
awk '/12/ { print $0 }/21/ { print $0 }' mail-list data
直接在awk後面寫上兩個檔案,即可對兩個檔案進行匹配
那麼,如果有一個檔案不存在呢 ,分別寫錯第二個和第一個檔案,得出結果如下:
通過這個結果可以看出,寫錯第二個檔案時,不影響第一個檔案的處理,但是寫錯第一個檔案,那麼第二個檔案也不會進行處理。 所以我們可以得出結果當前面的檔案出錯,後面的不會進行,但是後面檔案的正確與否不影響前面檔案的處理
8. 匹配當前目錄下十一月所修改的檔案大小總和
ls -l | awk '$6 == "Nov" { sum += $5 }END { print sum }'
我們在這裡先查看了檔案的特點,發現第六列是月份,第五列是大小,那麼我們就可以使用上面的命令,指定第六列,然後對第五列的值進行累加,最後輸出 這裡面有一個$5,$6的引數,這是指定列, $n意思是指定第n列(欄位)
9. 命令換行
有時候我們的命令會輸的太長了,那麼我們可以使用\來換行
print \
"hello,world"\
}'
注意,在輸入\進行換行時,不要寫後半個’ 不然會出錯
總結: awk是個非常複雜的工具,要想學好學精還有很長的路要走,需要不懈的努力,上面的用法只是最最基礎的一部分,如果有機會,我會在後面繼續補充awk的用法。