咱們知道 Linux 三劍客,它們分別是:grep
、sed
、awk
。在前邊已經講過 grep 和 sed,沒看過的同窗能夠直接點擊閱讀,今天要分享的是更爲強大的 awk
。正則表達式
sed 能夠實現非交互式的字符串替換,grep 可以實現有效的過濾功能。與二者相比,awk 是一款強大的文本分析工具,在對數據分析並生成報告時,顯得尤其強悍。編程
awk 強大的功能,是通常 Linux 命令沒法比擬的。在本文中,我不會告訴你 awk 也是一種編程語言,省得會嚇到你。咱們只需把它當作 Linux 下一款強大的文本分析工具便可。數組
這篇文章,我仍然秉持着 實用、實踐 原則,提供大量的示例,但不會面面俱到。經過本文能夠幫助你,快速將 awk 運用起來,這些東西足夠應付工做中大多數應用場景。網絡
學習具體使用前,先來看下 awk 能幹些什麼事情:app
1. 可以將給定的文本內容,按照咱們指望的格式輸出顯示,打印成報表。負載均衡
2. 分析處理系統日誌,快速地分析挖掘咱們關心的數據,並生成統計信息;tcp
3. 方便地用來統計數據,好比網站的訪問量,訪問的 IP 量等;編程語言
4. 經過各類工具的組合,快速地彙總分析系統的運行信息,讓你對系統的運行了如指掌;函數
5. 強大的腳本語言表達能力,支持循環、條件、數組等語法,助你分析更加複雜的數據;工具
……
固然 awk 不只能作這些事情,當你將它的用法融匯貫通時,能夠爲所欲爲的按照你的意願,來進行高效的數據分析和統計。
不過咱們須要知道,awk 不是萬能的,它比較擅長處理格式化的文本,好比 日誌、csv 格式數據等;
咱們先來簡單瞭解 awk 基本工做原理,經過下邊的圖文講述,但願你能瞭解 awk 究竟是如何工做的。
awk 基本命令格式
結合下圖來詳細說明 awk 工做原理
BEGIN
標識的 {}
中的命令;BEGIN
大括號中命令的後,開始執行 body
命令;\n
分割的內容爲一條 記錄,其實就是行的概念;body
塊中的命令,每讀取一行,執行一次 body
,最終完成 body
執行;END
命令,一般會在 END
中輸出最後的結果;awk 是輸入驅動的,有多少輸入行,就會執行多少次 body
命令。
咱們在下邊的示例學習中,要時刻記着:記錄 (Record) 就是行,字段 (Field) 就是列,BEGIN
是預處理階段,body
是 awk 真正工做的階段,END
是最後處理階段。
從下邊內容開始,咱們直接進入到實戰。爲了方便舉例,我先把以下信息保存到 file.txt
好了,咱們先來一個最簡單最經常使用的 awk 示例,輸出第 一、四、8 列:
大括號裏邊的就是 awk 語句,只能被單引號包含,其中,$1..$N
表示第幾列,$0
表示整個行內容
再來看下 awk
比較實用的功能 格式化輸出。和 C
語言的 printf
格式輸出是一毛同樣,我我的特別喜歡這種格式化方式,而不是 C++
中的流的方式。
%s
表示字符串佔位符,-4
表示列寬度爲 4
,且左對齊,咱們還能夠根據須要,列出更復雜的格式來,這裏先不詳細舉例了。
(一)過濾記錄
有些數據可能不是你想要的,能夠根據須要進行過濾
上邊的過濾條件爲,第 3 列爲 root 且第 6 列爲 10 的行,纔會被輸出。
awk 支持各類比較運算符號 !=
、>
、<
、>=
、<=
,其中 $0
表示整行的全部內容。
(二)內置變量
awk 內置了一些變量,更方便咱們對數據的處理
過濾第 3 列爲 root 用戶,以及第 2 行內容,且打印時輸出行號。NR
表示當前第幾行,NF
表示當前行有幾列。
(三)指定分隔符
咱們的數據,不老是以空格爲分隔符,咱們能夠經過 FS
變量指定分隔符。
咱們指定分隔符爲 2019
,這樣就將行內容分割爲了兩部分,將 2019
替換成了 *
上邊的命令也能夠經過 -F
選項指定分割符
若是你須要指定多個分隔符,能夠這樣作 -F '[;:]'
。相信聰明的你,必定可以理解並融會貫通的。
一樣,awk 能夠指定輸出時的分隔符,經過 OFS
變量來設置
輸出時,各字段用 OFS
指定的符號進行了分隔。
(一)條件匹配
列出 root 用戶的全部文件,以及第一行文件
上邊匹配第三列中包含 root
的行,~
其實就是正則表達式的匹配。
一樣,awk 能夠像 grep 同樣匹配某一行,就像這樣
另外,能夠這樣 /Aug|Dec/
匹配多個關鍵詞。
模式取反可使用 !
符號
(二)拆分文件
咱們來作一件有意思的事情,能夠將文本信息拆分爲多個文件,下邊命令按照月份(第5列)將文件信息拆分爲多個文件
awk 支持重定向符號 >
,直接將每行內容重定向到月份命名的文件了,固然你也能夠把指定的列輸出到文件
(三)if 語句
複雜的條件判斷,可使用 awk 的 if
語句,awk 的強大正由於它是個腳本解釋器,擁有通常腳本語言的編程能力,下邊示例經過稍微複雜的條件進行拆分文件
要注意,if
語句是在大括號裏邊的。
(四)統計
統計當前目錄下,全部 *.c
、*.h
文件所佔用空間大小總和
第 5 列表示文件大小,每讀取一行就會將該文件大小計算到 sum
變量中,在最後 END
階段打印出 sum
,也就是全部文件的大小總和。
再來看一個例子,統計每一個用戶的進程佔用了多少內存,注意取值的是 RSS 那一列
這裏用到了 數組 和 for 循環,值得一提的是,awk 的數組能夠理解爲字典或 Map
,key 能夠是數值和字符串,這種數據類型在平時很經常使用。
(五)字符串
經過下邊簡單示例,展現 awk 對字符串操做的支持
awk 內置支持一系列的字符串函數,length
計算字符串長度,toupper
函數轉換字符串爲大寫。
爲了從總體上理解 awk 工做機制,咱們再來看一個綜合的示例,假設有一個學生成績單:
因爲此示例程序稍顯複雜,在命令行上不易讀,另外呢,也想經過此案例介紹另一種 awk 的執行方式,咱們的 awk 腳本以下:
執行 awk 結果以下
咱們能夠將複雜的 awk 語句寫入腳本文件 cal.awk
,而後經過 -f
選項指定從腳本文件執行。
BEGIN
階段,咱們初始化了相關變量,並打印了表頭的格式body
階段,咱們讀取每一行數據,計算該學科和該同窗的總成績END
階段,咱們先打印了表尾的格式,並打印總成績,以及計算了平均值這個簡單示例,完整的體現了 awk 的工做機制和原理,但願經過此示例可以幫你真正理解 awk 是如何工做的。
經過上述的示例,咱們學習到了 awk 的工做原理,下邊咱們來總結下幾個概念和經常使用的知識點。
(一)內置變量
1. 每一行內容記錄,叫作記錄,英文名稱 Record
2. 每行中經過分隔符隔開的每一列,叫作字段,英文名稱 Field
明確這幾個概念後,咱們來總結幾個重要的內置變量:
NR
:表示當前的行數;NF
:表示當前的列數;RS
:行分隔符,默認是換行;FS
:列分隔符,默認是空格和製表符;OFS
:輸出列分隔符,用於打印時分割字段,默認爲空格ORS
:輸出行分隔符,用於打印時分割記錄,默認爲換行符(二)輸出格式
awk 提供 printf
函數進行格式化輸出功能,具體的使用方式和 C
語法基本一致。
基本用法
經常使用的格式化方式:
%d
十進制有符號整數%u
十進制無符號整數%f
浮點數%s
字符串%c
單個字符%e
指數形式的浮點數%x
%X
無符號以十六進制表示的整數%0
無符號以八進制表示的整數%g
自動選擇合適的表示法\n
換行符\t
Tab符(三)編程語句
awk 不只是一個 Linux 命令行工具,它實際上是一門腳本語言,支持程序設計語言全部的控制結構,它支持:
(四)經常使用函數
awk 內置了大量的有用函數功能,也支持自定義函數,容許你編寫本身的函數來擴展內置函數。
這裏只簡單羅列一些比較經常使用的字符串函數:
index(s, t)
返回子串 t 在 s 中的位置length(s)
返回字符串 s 的長度split(s, a, sep)
分割字符串,並將分割後的各字段存放在數組 a 中substr(s, p, n)
根據參數,返回子串tolower(s)
將字符串轉換爲小寫toupper(s)
將字符串轉換爲大寫這裏只簡單總結一些經常使用的字符串功能函數,具體使用方法,還須要你參照前邊的示例程序,觸類旁通,運用到實際問題中。
本次分享就到這裏了,謝謝你們的閱讀,我是肖邦。關注個人公衆號「編程修養」,大量的乾貨文章等你來!
公衆號後臺回覆「1024」有驚喜!
推薦閱讀: