linux awk 命令實用手冊

在這裏插入圖片描述

0,簡介

Linux awk 是一個實用的文本處理工具,它不僅是一款工具軟件,也是一門編程語言awk 的名稱來源於其三位作者的姓氏縮寫,其作者分別是Alfred AhoPeter WeinbergerBrian Kernighan

如果你在linux 系統中追蹤awk,可以看到其最終指向的是/usr/bin/gawk,也就是gawk 命令。其GNU官方手冊 權威且全面,但對於初學者並不是很友好,因爲內容非常多,你可能不知從何看起。對於普通用戶,一般也用不到非常複雜的功能。

如果一個文件由規則的多個列組成,則非常適合使用awk 來處理。本文介紹awk 常用方法,對於普通使用者應該是足夠了。

1,基本概念

awk 命令會對文本文件每一行進行處理,其語法格式如下:

awk `參數` `pattern {action}` `filename`

pattern 是要匹配的規則,action 是要執行的動作,只有匹配了pattern,纔會執行動作action

這句命令的含義是:對於文件filename 的每一行,如果能夠符合條件pattern,則執行動作action。如果不寫pattern,則表示對於文件filename的每一行,都進行action 處理。

1.1,參數

awk 最常使用的參數是-F,其後跟一個分隔符或者正則表達式,其表示的意思是以怎樣的規則對每一行進行分割。 默認是空格Tab鍵

1.2,pattern

pattern 可以是下表中的任意一項:

pattern 說明
/正則表達式/ 正則寫在兩個/ 之間
關係表達式 awk 中支持的關係運算符組成
模式匹配表達式 ~(匹配)和!~(不匹配)組成
BEGIN{語句} 在處理第一行文本之前,執行BEGIN 塊中的語句,可以在這裏進行一些變量初始化等操作
END{語句} 在處理完最後一行文本之後,執行END 塊中的語句
/規則1/,/規則2/ 這是一個範圍模板,只處理規則1第一次出現與規則2第一次出現之間的行

1.3,action

actionawk 語句組成,比如print,用於輸出。

2,awk 內置變量

awk 中內置了很多變量,來方便使用,這裏介紹一些常用的:

awk 內置變量 含義
FS 表示分隔符,類似-F 參數的功能
$0 一行的完整內容
$n 分隔符隔開的第n列,比如$1 表示第一列
FILENAME 當前文件名
NR 當前行數,即當前行是第幾行
NF 當前行的列數,即當前行分割符分成了幾列
IGNORECASE 如果爲真,表示忽略大小寫進行匹配

3,awk 內建函數

awk 常用函數如下:

函數 含義
tolower() 字符串轉小寫
toupper() 字符串轉大寫
length() 計算字符串長度
split() 字符串分割
systime() Unix 時間戳
strftime() 時間格式化,用法同C語言中的strftime 函數
rand() 隨機數
sin() 正弦
cos() 餘弦
sqrt() 平方根
exp() 求冪

4,awk 運算符

awk 支持如下常用運算符

運算符 含義
+ - * / & 加,減,乘,除,求餘
= += -= *= /= %= ^= **= 賦值運算符
< <= > >= != == 比較運算符
空格 用於連接字符串,使用較多
|| 邏輯
&& 邏輯
! 邏輯
~ 匹配
!~ 不匹配

5,awk 使用案例

假如,我們有如下文件,分別爲姓名性別年齡成績等級省份

>>> cat log.txt 
_________________
小明,男,23,550^優秀---北京
小麗,女,22,560^優秀---河北
小磊,男,24,530^良好---河南
小召,男,23,540^優良---山東
小欣,女,23,545^優良---山西

5.1 使用-F

以逗號,分隔符,並將第1列,第2列和第3列輸出,如下:

>>> awk -F, '{print $1,$2,$3}' log.txt 
______________________________________
小明 男 23
小麗 女 22
小磊 男 24
小召 男 23
小欣 女 23

分隔符只有一個字符時,分割符可以緊挨-F,還有如下幾種寫法:

awk -F , '{print $1,$2,$3}' log.txt		#`分隔符`與`-F`之間有一個空格
awk -F',' '{print $1,$2,$3}' log.txt	#`分隔符`用單引號引住,並且緊挨`-F`
awk -F"," '{print $1,$2,$3}' log.txt	#`分隔符`用雙引號引住,並且緊挨`-F`
awk -F ',' '{print $1,$2,$3}' log.txt	#`分隔符`用單引號引住,與`-F`之間有空格
awk -F "," '{print $1,$2,$3}' log.txt	#`分隔符`用雙引號引住,與`-F`之間有空格

分隔符多個連續字符時,必須用雙引號或者單引號引住分割符,可以緊挨-F,也可以有空格

awk -F '---' '{print $2}' log.txt	#`分隔符`用單引號引住,與`-F`之間有空格
awk -F"---" '{print $5}' log.txt	#`分隔符`用雙引號引住,與`-F`之間沒有空格

以上兩個命令輸出的內容一樣,此時分隔符---,每一行都被分成了兩列,如下:

小明,男,23,550^優秀 北京
小麗,女,22,560^優秀 河北
小磊,男,24,530^良好 河南
小召,男,23,540^優良 山東
小欣,女,23,545^優良 山西

當有多個單獨的分割符時,將多個分隔符寫在中括號[]中,如下,表示以, 或者以--- 爲分隔符:

>>> awk -F "[,^]" '{print $1, $2, $3, $4, $5}' log.txt 
________________________
小明 男 23 550 優秀---北京
小麗 女 22 560 優秀---河北
小磊 男 24 530 良好---河南
小召 男 23 540 優良---山東
小欣 女 23 545 優良---山西

5.2 使用內置變量

我們用變量NR輸出當前行號,變量NF輸出當前行的列數,變量FILENAME輸出當前文件名,如下:

>>> awk -F"---" '{print NR, $1, $2, NF, FILENAME}' log.txt
__________________________________________________________
1 小明,男,23,550^優秀 北京 2 log.txt
2 小麗,女,22,560^優秀 河北 2 log.txt
3 小磊,男,24,530^良好 河南 2 log.txt
4 小召,男,23,540^優良 山東 2 log.txt
5 小欣,女,23,545^優良 山西 2 log.txt

5.3 如何連接字符串

我們將每一列使用豎線| 分割,方法是將分隔符雙引號引住,然後緊挨變量,如下:

>>> awk -F"---" '{print NR"|"$1"|"$2"|"NF"|"FILENAME}' log.txt
__________________________________
1|小明,男,23,550^優秀|北京|2|log.txt
2|小麗,女,22,560^優秀|河北|2|log.txt
3|小磊,男,24,530^良好|河南|2|log.txt
4|小召,男,23,540^優良|山東|2|log.txt
5|小欣,女,23,545^優良|山西|2|log.txt

5.3 使用內置函數

使用內置函數systime() 輸出時間戳,如下:

>>> awk -F"---" '{print NR"|"$1"|"$2"|"NF"|"FILENAME"|"systime()}' log.txt
—————————————————————————————————————————————
1|小明,男,23,550^優秀|北京|2|log.txt|1587022443
2|小麗,女,22,560^優秀|河北|2|log.txt|1587022443
3|小磊,男,24,530^良好|河南|2|log.txt|1587022443
4|小召,男,23,540^優良|山東|2|log.txt|1587022443
5|小欣,女,23,545^優良|山西|2|log.txt|1587022443

使用length 輸出行長度大於5 的行:

>>> awk 'length>5' log.txt
——————————————————————————
小明,男,23,550^優秀---北京
小麗,女,22,560^優秀---河北
小磊,男,24,530^良好---河南
小召,男,23,540^優良---山東
小欣,女,23,545^優良---山西

5.4 使用pattern

使用pattern 只輸出 同學信息,$0 表示每一行的原始內容,如下:

>>> awk '/男/ {print NR"|"$0}' log.txt
__________________________
1|小明,男,23,550^優秀---北京
3|小磊,男,24,530^良好---河南
4|小召,男,23,540^優良---山東

5.5 使用邏輯非!

使用邏輯非!,輸出不爲的學生信息:

>>> awk '!/男/ {print NR"|"$0}' log.txt
__________________________
2|小麗,女,22,560^優秀---河北
5|小欣,女,23,545^優良---山西

5.6 使用關係表達式

使用關係表達式,輸出年齡爲23 的學生信息:

# 以逗號分割後的第三列爲年齡
>>> awk -F, '$3==23 {print $3, $0}' log.txt
____________________________
23 小明,男,23,550^優秀---北京
23 小召,男,23,540^優良---山東
23 小欣,女,23,545^優良---山西

也可以寫成如下方式,輸出年齡爲23或25 的學生信息:

>>> awk -F, '$3==23 || $3==25' log.txt
________________________
小明,男,23,550^優秀---北京
小召,男,23,540^優良---山東
小欣,女,23,545^優良---山西

5.7 使用模式匹配表達式

使用模式匹配表達式,輸出年齡爲24 的學生信息:

awk -F, '$3 ~/24/ {print $3, $0}' log.txt
24 小磊,男,24,530^良好---河南

5.8 使用if 語句

awk 也支持if 語句,輸出年齡爲22 的學生信息,if 語句寫在大括號{}內:

>>> awk -F, '{if($3==22) print $3, $0}' log.txt
___________________________
22 小麗,女,22,560^優秀---河北

5.9 使用NR 輸出基數行

# `NR % 2 == 1` 爲基數行
>>> awk -F, 'NR % 2 == 1 {print NR, $0}' log.txt
——————————————————————————
1 小明,男,23,550^優秀---北京
3 小磊,男,24,530^良好---河南
5 小欣,女,23,545^優良---山西

5.10 使用NF 輸出倒數第一列

$(NF) 爲倒數第1列,$(NF-1) 爲倒數第2列,$(NF-2) 爲倒數第3列,依次類推。

如下輸出倒數第1列:

>>> awk -F, '{print $(NF)}' log.txt
______________
550^優秀---北京
560^優秀---河北
530^良好---河南
540^優良---山東
545^優良---山西

5.11 使用BEGIN 塊

BEGIN 塊中可以是任意多個合法的awk 語句

>>> awk -F, 'BEGIN{print "姓名", "性別", "年齡"} {print $1, $2, $3}' log.txt 
____________
姓名 性別 年齡
小明 男 23
小麗 女 22
小磊 男 24
小召 男 23
小欣 女 23

5.12 使用END 塊

END 塊中可以是任意多個合法的awk 語句BEGIN 塊END 塊可以一起使用。

>>> awk -F, 'BEGIN{print "姓名", "性別", "年齡"} {print $1, $2, $3} END{print "共有"NR"行信息"}' log.txt 
____________
姓名 性別 年齡
小明 男 23
小麗 女 22
小磊 男 24
小召 男 23
小欣 女 23
共有5行信息

5.13 使用範圍模板

輸出小麗和小欣之間的行數據:

>>> awk '/小麗/,/小欣/' log.txt 
______________________________
小麗,女,22,560^優秀---河北
小磊,男,24,530^良好---河南
小召,男,23,540^優良---山東
小欣,女,23,545^優良---山西

(完。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章