1. 程式人生 > >文字處理三劍客之AWK

文字處理三劍客之AWK

AWK簡介

   AWK是一件上古神器,用這句話來形容AWK是最貼切不過了。
   縱觀計算機發展的歷史,我們發現,awk幾乎是伴隨著計算機作業系統的發展一路走來。1970年作為計算機計時元年,誕生了UNIX和C語言這兩種偉大的事物。在這之後,計算機技術飛速發展,1977年貝爾實驗室搞出來一款文字處理神器AWK,之所以起名AWK是因為採用了三位創始人Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的名字首字母。想想也是比較有意思的一件事情。
   1991年,linus開源了Linux作業系統,至此,計算機進入了迅猛發展的階段。AWK作為一種神器自然而然地整合到了Linux中,於是作為文字處理三劍客之一的AWK就這樣一直使用到了現在。
   awk有3個不同版本: awk、nawk和gawk,未作特別說明,一般指gawk,gawk 是 awk 的 GNU 版本。AWK其實是一種類似程式語言的存在,它集成了程式語言的諸多特性,使用起來靈活多變。本文將簡要介紹AWK的使用,力圖做到簡明扼要。

AWK 基本用法和常見選項

awk 的基本用法一般有下面幾種

  • awk [options] ‘program’ var=value file…
  • awk [options] -f programfile var=value file…
  • awk [options] 'BEGIN{ action;… } pattern{ action;… } END{action;… }' file ...

awk 程式通常由:BEGIN語句塊、能夠使用模式匹配的通用語句塊、END語句塊,共3部分組成program通常是被單引號或雙引號中

awk 常用選項

  • -F :指明輸入時用到的欄位分隔符
  • -v var=value : 自定義變數

pattern和action

AWK program 的基本格式為 program:pattern{action statements;..}
對於AWK來說,是支援正則表示式(pattern)的,由此可見正則表示式在計算機應用中是多麼的重要。

  • pattern部分決定動作語句何時觸發及觸發事件,如BEGIN,END
  • action statements對資料進行處理,放在{}內指明,如 print printf

分割符、域(也可以理解為列,欄位,屬性…)和記錄(可以理解為一條資料,記錄)

這裡應該詳細的介紹一下AWK的處理機制。AWK 通常被用作報告生成器,格式化文字輸出。
就拿我們最熟悉的 /etc/passwd 檔案來說,如果我們指定的分隔符為冒號(:),那麼AWK會將這段文字中被冒號隔開的字元理解為域,文字中的每一行作為一條記錄。 就像下圖表現的這樣。



那麼 具體來說,到底應該如何使用呢?

# 取出當前系統中所有的使用者 和密碼
# 實際上就是取出 /etc/paswdd   的第一列和第三列

[[email protected] ~]#awk -F: -v  OFS="**" '{print $1,$3}' /etc/passwd
root**0
bin**1
daemon**2
adm**3
lp**4
sync**5
shutdown**6
halt**7
.....


AWK 工作原理

  第一步:執行BEGIN{action;… }語句塊中的語句
  第二步:從檔案或標準輸入(stdin)讀取一行,然後執行pattern{action;… }語句塊,它逐行掃描檔案,從第一行到最後一行重複這個過程,直到檔案全部被讀取完畢。
  第三步:當讀至輸入流末尾時,執行END{action;…}語句塊。
  BEGIN語句塊在awk開始從輸入流中讀取行之前被執行,這是一個可選的語句塊,比如變數初始化、列印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中。
  END語句塊在awk從輸入流中讀取完所有的行之後即被執行,比如列印所有行的分析結果這類資訊彙總都是在END語句塊中完成,它也是一個可選語句塊。
  pattern語句塊中的通用命令是最重要的部分,也是可選的。如果沒有提供pattern語句塊,則預設執行{ print },即列印每一個讀取到的行,awk讀取的每一行都會執行該語句塊。

AWK 變數

AWK 中內建了很多的變數,同時也可以自定變數來使用。下面介紹一下AWK中內建的變數。

變數名稱 作用 舉例
FS 輸入欄位分隔符,預設為空白字元 awk -v FS=':' '{print $1,FS,$3}' /etc/passwd awk –F: '{print $1,$3,$7}' /etc/passwd
OFS 輸出欄位分隔符,預設為空白字元 awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd
RS 輸入記錄分隔符,指定輸入時的換行符,原換行符仍有效 awk -v RS=' ' '{print }' /etc/passwd
ORS 輸出記錄分隔符,輸出時用指定符號代替換行符 awk -v RS=' ' -v ORS='###' '{print }' /etc/passwd
NF 欄位數量 awk -F: '{print NF}' /etc/fstab awk -F: '{print $(NF-1)}' /etc/passwd
NR 行號 awk '{print NR}' /etc/fstab ; awk END'{print NR}' /etc/fstab
FNR 各檔案分別計數,行號 awk '{print FNR}' /etc/fstab /etc/inittab
FILENAME 當前檔名 awk '{print FILENAME}' /etc/fstab
ARGC 命令列引數的個數 awk '{print ARGC}' /etc/fstab /etc/inittab awk 'BEGIN {print ARGC}' /etc/fstab /etc/inittab
ARGV 陣列,儲存的是命令列所給定的各引數 awk 'BEGIN {print ARGV[0]}' /etc/fstab /etc/inittab awk 'BEGIN {print ARGV[1]}' /etc/fstab /etc/inittab

printf 命令

AWK中有一個與print類似的命令叫做printf。printf能夠對處理之後的字串格式化輸出。
在shell 中也有一個這樣的內建命令,二者的使用是類似的。同時在使用printf的時候也可以參考C語言的輸出方式來理解。

格式化輸出:printf “FORMAT”, item1, item2, …
(1) 必須指定FORMAT
(2) 不會自動換行,需要顯式給出換行控制符,\n
(3) FORMAT中需要分別為後面每個item指定格式符

格式符:與item一一對應

  • %c: 顯示字元的ASCII碼
  • %d, %i: 顯示十進位制整數
  • %e, %E:顯示科學計數法數值
  • %f:顯示為浮點數
  • %g, %G:以科學計數法或浮點形式顯示數值
  • %s:顯示字串
  • %u:無符號整數
  • %%: 顯示%自身

    修飾符:

  • #[.#]:第一個數字控制顯示的寬度;第二個#表示小數點後精度,%3.1f

  • -: 左對齊(預設右對齊) %-15s
  • +:顯示數值的正負符號 %+

試驗一 取出當前系統中所有的使用者 和密碼

# 取出當前系統中所有的使用者 和密碼
# 實際上就是取出 /etc/paswdd   的第一列和第三列
[[email protected] ~]#awk -F: '{printf "%-20s %-10d \n" ,$1,$3}' /etc/passwd
root                 0          
bin                  1          
daemon               2          
adm                  3          
lp                   4          
sync                 5          
shutdown             6    

.......

試驗二 取出當前系統中硬碟的使用率

# 取出當前系統中硬碟的使用率
[root@localhost ~]#df | grep '^/dev/sd'| awk '{printf "Devname:%s Use:%s\n",$1,$5}'
Devname:/dev/sda2 Use:22%
Devname:/dev/sda3 Use:1%
Devname:/dev/sda1 Use:17%

AWK 模式匹配

AWK 支援模式匹配,也就是說,AWK根據pattern條件,過濾匹配的行,再做處理

  • 如果未指定:空模式,匹配每一行
  • /regular expression/:僅處理能夠模式匹配到的行,需要用/ /括起來 ,這與sed是相似的。
  • relational expression: 關係表示式,結果為“真”才會被處理
    • 真:結果為非0值,非空字串
    • 假:結果為空字串或0值
  • line ranges:行範圍 startline,endline:/pat1/,/pat2/ 不支援直接給出數字格式 ,處理匹配這兩個模式之間的行的範圍。
  • BEGIN/END模式:
    • BEGIN{}: 僅在開始處理檔案中的文字之前執行一次
    • END{}:僅在文字處理完成之後執行一次

#列印 root 行到nobody行之間的第一列
[root@localhost ~]#awk -F: '/^root\>/,/^nobody\>/{print $1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody

AWK 控制語句

前面我們說過,AWK是一種類似於程式語言的文字處理器。之所以這樣說,是因為AWK中支援豐富的控制語句。這些控制語句與C語言很相似,可以結合C語言來理解,在使用上比shell要簡單很多。

AWK 中的控制結構舉例

  • { statements;… } 組合語句
  • if(condition) {statements;…} if語句
  • if(condition) {statements;…} else {statements;…} if else 語句
  • while(conditon) {statments;…} while 語句
  • do {statements;…} while(condition) do while 迴圈
  • for(expr1;expr2;expr3) {statements;…} for 迴圈
  • switch case 語句
  • break 語句
  • continue 語句
  • delete array[index]
  • delete array
  • exit

試驗一 /etc/passwd 中UID 小於1000輸出系統使用者,大於1000 輸出普通使用者

[[email protected] ~]#awk -F: '{if($3>=1000){printf "Common User: %s \n",$1}else{printf "root or sysuser:%s\n",$1}}' /etc/passwd  
root or sysuser:root
root or sysuser:bin
root or sysuser:daemon
root or sysuser:adm
......
Common User: basher 
Common User: sh 
Common User: nologin 
Common User: quliang 
root or sysuser:apache
root or sysuser:quagga

試驗二 輸出/etc/grub2.cfg 檔案中以linux16開頭的行中每個欄位的長度

[[email protected] ~]#awk '/^[[:space:]]*linux16/{i=1;while(i<NF){print $i,length($i);i++}}' /etc/grub2.cfg
linux16 7
/vmlinuz-3.10.0-514.el7.x86_64 30
root=UUID=0115740e-4b33-4387-bd21-722a969f7fd8 46
ro 2
crashkernel=auto 16
rhgb 4
quiet 5
linux16 7
/vmlinuz-0-rescue-ecc418eb09cb4d05969fbaafae323000 50
root=UUID=0115740e-4b33-4387-bd21-722a969f7fd8 46
ro 2
crashkernel=auto 16
rhgb 4
quiet 5

AWK 函式

AWK 函式的使用方式與它的控制結構一樣,與C語言很類似,可以結合下面的示例好好的理解一下。
同時AWK本身有一些簡單易用的庫函式,可以直接在AWK命令中進行使用。

內建函式

AWK 中的內建函式如下表所示。

變數名稱 作用
rand() 返回0和1之間一個隨機數
length([s]) 返回指定字串的長度
sub(r,s,[t]) 對t字串進行搜尋r表示的模式匹配的內容,並將第一個匹配的內容替換為s
gsub(r,s,[t]) 對t字串進行搜尋r表示的模式匹配的內容,並全部替換為s所表示的內容
split(s,array,[r]) 以r為分隔符,切割字串s,並將切割後的結果儲存至array所表示的陣列中,第一個索引值為1,第二個索引值為2,…

試驗一 將8008:08:08 08:08:08 中冒號替換

[[email protected] ~]#echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
2008-08:08 08:08:08
[[email protected] ~]#echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)'
2008-08-08 08-08-08

試驗二 統計網路訪問中同一IP 的訪問次數


[root@localhost ~]#netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}
END{for (i in count) {print i,count[i]}}'
0.0.0.0 6
172.18.251.85 1

自定義函式

自定義函式的格式 與C語言的函式格式很相似,並且還具有形式引數和實際引數,返回值也與bash 中有所不同。


function name ( parameter, parameter, ... ) {
    statements
    return expression
}

我們定義一個函式,用來返回兩個值中的最大值


[[email protected] test]#cat f1.txt
function max ( param1,param2) {
    param1 > param2 ? var=param1 :var=param2
    return var
}

BEGIN{print max(a,b)}
[[email protected] test]#awk -v a=10 -v b=20 -f f1.txt 
20

AWK是十分強大的,通過上面的介紹我們也僅僅是介紹了AWK的一些皮毛而已,在實際生產中還需要根據實際需要查閱相關資料來實現我們的需求才可以。

相關推薦

文字處理三劍客AWK

AWK簡介    AWK是一件上古神器,用這句話來形容AWK是最貼切不過了。    縱觀計算機發展的歷史,我們發現,awk幾乎是伴隨著計算機作業系統的發展一路走來。1970年作為計算機計時元年,誕生了UNIX和C語言這兩種偉大的事物。在

Linux進階篇--文字處理三劍客AWK

Linux進階篇–文字處理三劍客之AWK 本章概要 awk介紹 awk基本用法 awk變數 awk格式化 awk操作符 awk條件判斷 awk迴圈 awk陣列 awk函式 呼叫系統命令 一、 awk介紹 awk:Aho, Weinberger, Kerni

文字處理三劍客awk(原創)

AWK是一種優良的文字處理工具,Linux及Unix環境中現有的功能最強大的資料處理引擎之一。這種程式設計及資料操作語言(其名稱得自於它的創始人阿爾佛雷德·艾侯(Alfred Aho)、彼得·溫伯格(Peter Jay Weinberger)和布萊恩·柯林漢(Brian Wi

Linux文字處理三劍客awk

awk簡介 awk是一種解釋執行的程式語言,用來專門處理文字資料,其名稱是由它們設計者的名字縮寫而來 ———Afred Aho,Peter Weinberger與 Brian Kernighan。常見版本有: - awk: 最原初的版本,它由 AT&am

文本處理三劍客awk

awk文本處理三劍客之awk awk: 報告生成器,格式化文檔輸出; awk(gawk):pattern scanning and processing language 格式:awk [options...] 'program' file progra

文本處理三劍客awk(原創)

創建 兩個 位置 正則 ack 最大 align common 因此 文本處理三劍客之awk(原創)AWK是一種優良的文本處理工具,Linux及Unix環境中現有的功能最強大的數據處理引擎之一。這種編程及數據操作語言(其名稱得自於它的創始人阿爾佛雷德·艾侯(Alfred A

Linux文本處理三劍客awk(一)

awk變量 信息 tro 不同 當前 block 文件中 是否 定義變量   AWK是一個優良的文本處理工具,Linux及Unix環境中現有的功能最強大的數據處理引擎之一。其名稱得自於它的創始人阿爾佛雷德·艾侯、彼得·溫伯格和布萊恩·柯林漢姓氏的首個字母

02-shell文字處理三劍客sed

sed 是流編輯器,但是它不會修改原始檔。 sed (流文字編輯器) 用法:sed OPTIONS… [SCRIPT] [INPUTFILE…] -r: 使用擴充套件的正則表示式; -n, –quiet, –silent: 不輸出模式空間的內容; -i:直接編輯原檔案; -

01-shell文字處理三劍客grep

開篇:哈嘍,今天我想寫寫shell程式設計,打算平均一天一篇吧,這樣一個月後就可以進步比較多。 先從shell文字處理三劍客grep、sed、awk開始。聽說啊,要是我不會這個命令,就不好意思說自己會shell程式設計。 1 grep是什麼意思? grep: Global se

文字處理三劍客grep

grep:根據使用者指定的“模式”對目標文字進行匹配檢查,列印匹配到的行 模式:用正則表示式字元所編寫的過濾條件 grep [option] pattern [file...] --color=auto:對匹配到的文字著色顯示 -v:顯示不能夠被pattern匹配到的行 -

4.shell程式設計-文字處理三劍客sed

4.1.sed的選項  sed,流編輯器。對標準輸出或檔案進行逐行處理。 語法格式 第一種:stdout | sed [option] "pattern command" 第二種:sed [option] "pattern command" file  選項 -n&

運維路-文字處理-三劍客(grep、sed、awk

轉載:https://blog.csdn.net/zisefeizhu/article/details/82526749 目錄  grep 支援的正則 描述 輸出控制 描述 內容行控制 描述 示例: sed Usage: 命令 描述 地址 描述 匹配刪除(d)  替

Linux文字處理三劍客awk、sed、grep入門

AWK命令簡介 AWK是一門解釋型的程式語言,它的名字來源於它的三位作者的姓氏:Alfred Aho,Peter Weinberger和Brian Kernighan。AWK能夠應用於廣泛的計算和資料處理任務。所有的GNU/Linux發行版都自帶GAWK,即GNU AWK,

SHELL文字處理三劍客(sed、grep、awk

一、grep文字過濾器 1. 基本介紹 Global search regular expression and print out theline 全面搜尋研究正則表示式並顯示出來 grep命令是一種強大的文字搜尋工具根據使用者指定的

shell文字處理三劍客(awk sed grep)

一.grep:文字過濾器 根據正則表示式來工作,由正則表示式或者字元及基本的文字字元所編寫的過濾條件 tr 'a-z' 'A-Z' < file          ###把passwd中的小寫轉換為大寫 ^x      ###以x開頭的 x$      ###以

Shell程式設計5_文字處理三劍客(awk)

文字處理三劍客(awk) 1.awk介紹 AWK:三位創造者Aho、Weinberger和Kernighan統稱 官方定義:一個優秀的樣式掃描與處理工具 定位:AWK是一種用於處理文字的程式語言工具,主要用於格式化報文或從一個大的文字檔案中抽取資

文字處理三劍客 grep sed awk

一、正則表示式       正則表示式是對字串(包括普通字元(例如,a 到 z 之間的字母)和特殊字元(稱為“元字元”))操作的一種邏輯公式,就是用事先定義好的一些特定字元、及這些特定字元的組合,組成一個“規則字串”,這個 “規則字串”用來表達對字串的一種過濾邏輯。正則表示

linux文字處理三劍客(三):awk命令詳解

簡介 awk是一個強大的文字分析工具,相對於grep的查詢,sed的編輯,awk在其對資料分析並生成報告時,顯得尤為強大。簡單來說awk就是把檔案逐行的讀入,以空格為預設分隔符將每行切片,切開的部分再進行各種分析處理。 awk有3個不同版本: awk、nawk和gaw

謝煙客---------Linux文本處理三劍客grep

linux基礎Linux之文本處理三劍客介紹 awk 名稱得自於它的創始人阿爾佛雷德·艾侯、彼得·溫伯格和布萊恩·柯林漢姓氏的首個字母,它具備了一個完整的語言所應具有的幾乎所有精美特性,AWK是一個解釋器,三位創建者已將它正式定義為“樣式掃描和處理語言”。它允許您創建簡短的程序,這些程序讀取輸入文件、為

謝煙客---------Linux文本處理三劍客egre、fgrep

linux基礎egrep是grep的另一種模式,用-E選項(啟用或關閉命令的某個或某些功能),啟用擴展正則表達式引擎功能,使用擴展正則表達式的字符和純文本字符組合的PATTERN,對文本流逐行匹配檢查,將匹配到的字符串所在的行顯示至標準輸出fgrep,grep -F選項,關閉正則表達式引擎功能,以純文本字符組