awk 文本分析工具#
說明:
awk
是一種程式語言,用於在 linux/unix 下對文本和數據進行處理。數據可以來自標準輸入 (stdin)、一個或多個文件,或其它命令的輸出。它支持用戶自定義函數和動態正則表達式等先進功能,是 linux/unix 下的一個強大程式工具。它在命令行中使用,但更多是作為腳本來使用。awk
有很多內置的功能,比如數組、函數等,這是它和 C 語言的相同之處,靈活性是awk
最大的優勢。
語法:
awk [option] 'PATTERN{ACTION STATEMENTS}' FILE
awk 執行過程#
awk 程式結構#
結構 | 解釋 |
---|---|
BEGIN{ awk-commands } | 可省略,裡面的內容在 awk 讀取文件之前執行 |
/pattern/{ awk-commands } | 可省略,對於輸入的每一行,都会執行一次該部分代碼,可以添加 /parttern/ 對輸入行進行過濾 |
END{ awk-commands } | 可省略,裡面的內容在 awk 讀取文件完畢之後執行 |
示例#
# 準備如下文本內容
[root@localhost ~]# cat emp.txt
001 張三 1000 10
002 李四 2000 10
003 王五 3000 10
004 趙六 2000 20
005 小紅 1800 30
006 小麗 800 20
# 用awk命令輸出文本內容
[root@localhost ~]# awk '{print}' emp.txt
# 輸出文本內容,添加表頭和表的結尾(-------------------)
[root@localhost ~]# awk 'BEGIN{print "編號 姓名 工資 部門"}{print}END{print "-------------------"}' emp.txt
編號 姓名 工資 部門
001 張三 1000 10
002 李四 2000 10
003 王五 3000 10
004 趙六 2000 20
005 小紅 1800 30
006 小麗 800 20
-------------------
awk 命令選項#
選項 | 含義 |
---|---|
-F fs | 指定輸入文件分隔符(默認是空白字符),fs 是一個字符串或者是一個正則表達式 |
-v var=value | 賦值一個用戶定義變量 |
-f scriptfile | 從腳本文件中讀取 awk 命令 |
awk 使用方式:
- 命令行使用
直接在命令行裡執行
awk
命令
awk '{print}' emp.txt
- awk 腳本使用
將 awk 代碼寫在文件裡(一般以.awk 為文件擴展名), 通過 -f 選項執行
awk -f file.awk emp.txt
- shell 腳本使用
將 awk 命令寫到 shell 腳本裡,執行 shell 腳本
awk 模式和操作#
模式 | 含義 |
---|---|
/pattern/ | 正則表達式 |
關係表達式 | 使用運算符進行操作 |
模式匹配表達式 | ~ (匹配) !~ (不匹配) |
操作可以由一個或多個命令、函數、表達式組成,之間由換行符或分號隔開
awk 正則範圍:
/start/,/end/
NR==1,NR==5
從第 1 行開始第 5 行結束
示例#
# 輸出emp.txt包含'小'字的行
[root@localhost ~]# awk '/小/' emp.txt
# 輸出從包含'張'的行開始到包含'趙'的行結束
[root@localhost ~]# awk '/張/,/趙/' emp.txt
# 輸出前三行
[root@localhost ~]# awk 'NR<=3' emp.txt
[root@localhost ~]# awk 'NR==1,NR==3' emp.txt
[root@localhost ~]# awk 'NR>=1 && NR<=3' emp.txt
# 模式匹配則輸出
[root@localhost ~]# awk '666 ~ /[0-9]+/' emp.txt
當使用模式後,如果只是輸出行,
awk
語句部分可省略
awk 變量#
內置變量(預定義變量)#
變量 | 含義 |
---|---|
$0 | 執行過程中當前行的內容 |
$n | 當前記錄的第 n 個字段(分割後的第 n 列) |
NF | 當前行的字段數,$NF 表示一行中最後一個字段 |
NR | 當前行的行號 |
FS | 輸入字段分隔符(默認是空白字符,可使用 - v 指定) |
OFS | 輸出字段分隔符(默認是一個空格,可使用 - v 指定) |
RS | 輸入記錄分隔符(默認是一個換行符,可使用 - v 指定) |
ORS | 輸出記錄分隔符(默認是一個換行符,可使用 - v 指定) |
FILENAME | 當前文件的文件名 |
自定義變量#
- 使用 - v 選項定義
-v var=value
- 在
awk
程式中定義
awk 'BEGIN{var=value}'
傳遞外部變量#
-
使用
-v
選項可以給awk
命令傳遞一個外部變量 -
在命令最後使用
var=value
也可以傳遞一個外部變量
示例#
# 打印emp.txt每一行的內容、行號和字段數
[root@localhost ~]# awk '{print $0,NR,NF}' emp.txt
# 打印第1列、最後一列和倒數的2列的內容
[root@localhost ~]# awk '{print $1,$NF,$(NF-1)}' emp.txt
# 將文本內容按照 "部門 編號 姓名 工資" 的順序輸出
[root@localhost ~]# awk '{print $4,$1,$2,$3}' emp.txt
# 輸出第3行的第2個字段
[root@localhost ~]# awk 'NR==3{print $2}' emp.txt
# 統計每個部門的人數
[root@localhost ~]# awk '{print $NF}' emp.txt | uniq -c
# 將輸出字段分隔符修改為':' 並把輸出結果寫入emp.txt.bak文件
[root@localhost ~]# awk -v OFS=":" '{print $1,$2,$3,$4}' emp.txt > emp.bak.txt
[root@localhost ~]# awk -v OFS=":" 'NF=NF' emp.txt > emp.bak.txt
# 針對emp.txt.bak文件每一行數據,輸出: "編號:xxx,姓名:xxx,工資:xxx"
[root@localhost ~]# awk -F: '{print "編號:"$1",姓名:"$2",工資:"$3}' emp.bak.txt
# 自定義變量
# 方式一
[root@localhost ~]# echo | awk -v a=100 '{print a}'
# 方式二
[root@localhost ~]# echo | awk 'BEGIN{b=100;print b}'
# 傳遞外部變量
[root@localhost ~]# a='aaa'
[root@localhost ~]# b='bbb'
# 方式一
[root@localhost ~]# echo | awk -v v1=$a -v v2=$b '{print v1,v2}'
# 方式二
[root@localhost ~]# echo | awk '{print v1,v2}' v1=$a v2=$b
awk
中
- 要使OFS
變量生效,必須對字段進行操作(可以設置NF=NF
,NF+=0
,$1=$1
...)
格式化打印(printf)#
- 使用方式和 C 語言的
printf
一樣 print
顯示結果時以逗號分隔,結果會自動將這些內容用分隔符進行分隔,並且不需要添加換行符;printf
可以控制某一個字段的輸出格式,需要手動添加換行符
常用格式替換符:
符號 | 解釋 |
---|---|
%s | 字符串 |
%f | 浮點數 |
%d | 十進制整數 |
%c | ASCII 字符 |
%% | % 本身 |
常用轉義字符:
符號 | 解釋 |
---|---|
\n | 換行 |
\t | 水平制表符 |
\v | 垂直制表符 |
\r | 回車 |
\b | 後退 |
\f | 換頁 |
\a | 警告字符 |
\\ | \ 本身 |