awk 是一個報告生成器 , 文本編輯器 , 同時自身也是一種編程語言 ,它支持條件判斷、數組、循環等功能linux
功能 : 對文本數據進行彙總處理 , 對數據進行排版 . 正則表達式
注 : awk只能對讀入到內存中的信息進行處理 , 沒法對內容所在的原文件內容進行修改 , 想要修改原文件內容可使用sed命令來改shell
grep 、sed、awk被稱爲linux中的"三劍客" , 相對這三者來講 : grep 更適合單純的查找或匹配文本 ;sed 更適合編輯匹配到的文本 ;awk 更適合對文本進行較複雜格式處理編程
grep , sed 以及跟多的Linux 的 bash 用法可參考上篇博客 : http://www.javashuo.com/article/p-pyylwhvg-m.html 數組
一 .awk語法格式及基本使用
bash
語法一 : awk [選項] '/匹配模式/{處理動做1 , 處理動做2...}' 文件名編程語言
語法二 : awk [選項] 'BEGIN{動做}{處理動做1 , 處理動做2...}END{動做}' 文件名編輯器
說明 : BEGIN 是指在讀awk指定的文件以前要執行的操做 , END 是指在awk讀完指定的文件以後執行的操做 .ide
實例 : 顯示 /etc/passwd 文件中以 : (冒號)分隔的第一列內容 :
函數
說明 : 上圖命令中 -F : 指定以冒號分隔 , print $1 表示打印出第一列 . 若是不指示符號 , 默認符號爲空格 , 可使用命令 awk '{print $1}' /etc/passwd 對比一下上面的命令顯示出來的結果 .
awk的BEGIN , END 語句用法 :
在命令行中執行 : awk 'BEGIN{print "welcome to awk"}' 結果以下 :
執行命令 : awk -F: 'BEGIN{print "welcome to awk"}{print $1}END{print "bye bye"}' /etc/passwd ,從下圖能夠看出 , 打印出來的 /etc/passwd文件的第一列的開頭和節爲的內容分別爲命令 BEGIN 和 END 語句顯示的內容 :
二 . awk 的內置變量
關於awk的內置變量常見的有$0 , FS , OFS :
$0 # 保存當前的整行記錄的內容
例 : awk -F: '{print $0}' /etc/passwd , 這條命令顯示的是 /etc/passwd 文件的全部內容
FS # 輸入字段分隔符 , 默認是空白
例 : awk 'BEGIN{FS=":"}{print $1,$2}' /etc/passwd
OFS #輸出字段分隔符 , 默認爲空白
例: awk 'BEGIN{FS=":";OFS="@"}{print $1,$2}' /etc/passwd
除了這三種常見的內置變量以外 , 內置變量還有 :
NR #記錄號 , 每處理完一條記錄 , NR值就加1 , 記錄的是文件的總值
可使用命令 : awk -F: '{print NR,$0}' /etc/passwd 查看效果
FNR #處理多個文件時分別統計本身的NR值
可使用命令 : awk -F: '{print NR,$0}' /etc/passwd /etc/gshasow 查看效果
NF #表示當前行的字段數(number field)
可使用命令 : awk -F: '{print NF,$0}' /etc/passwd 查看效果
RS #輸入記錄分隔符(記錄是是行與行之間的分隔) , 默認是一個換行符
可使用命令 : awk -F: 'BEGIN{RS=":"}{print}' /etc/passwd 查看效果
ORS #輸出記錄分隔符
可使用命令 : awk 'BEGIN{ORS=":"}{print}' /etc/passwd 查看效果
以上內置函數不一一舉例 , 自行查看效果 ..
三 . awk的邏輯控制語句
前面說到 , awk自己就爲一門編程語言 , 因此它自己也自帶邏輯控制語句 , 如 if 條件語句 ,for 循環語句等 .
1 . 條件判斷 if :
格式 : {if(表達式) {語句 , 語句 ....}}
例 : awk -F: '{if($4>999){print $0}}' /etc/passwd # 顯示/etc/passwd 文件中gid大於999的信息
問 : 統計/etc/passwd文件中登陸shell爲/bin/bash有多少個?
答 : awk -F: '{if($NF=="/bin/bash"){i++}else{j++}}END{print "不是/bin/bash的有 :"j "\n是/bin/bash的有:"i}' /etc/passwd (建議掌握)
注: awk調用內置變量值的時候須要用$變量名 , 而調用自定義變量值的時候不須要$符號 .
2 . 循環語句:
舉例說明用法 :
while : 打印1-5數字 awk 'BEGIN{i=1;while(i<=5){print i ;i++}}'
for : 將文件/etc/passwd每一行打印10次 awk -F: '{for(i=1i<=10;i++){print $0}}' /etc/passwd
四 . 數組
例 :統計passwd文件中各類shell類型
awk -F: '{shell[$NF]++} END{for(i in shell){print i,shell[i]}}' /etc/passwd
shell[$NF]++定義了一個名稱爲shell的數組,$NF(即number field行中的字段數)在passwd中是shell名稱,for(i in shell) print i,shell[i],用for循環取出數據來,這時候i取的是下標,shell[i]是裏面存儲的數據,也是$NF出現的次數
五 . print
1 . print輸出 :
要點 : 各個輸出字段之間用逗號作分隔 , 而輸出默認是以空格作分隔
print 後面若是不指定字段 , 那麼會打印一整行
print 輸出是默認是有換行符的
例 : 打印與文件內容無關的
awk '{print "aaa"}' /etc/passwd 根據/etc/passwd內容的行數來循環執行print命令
\n換行符
awk -F: '{print $1"\n"$2}' /etc/passwd
\t製表符
awk -F: '{print $1"\t"$2}' /etc/passwd
打印一句話:root用戶的uid是0
awk -F: '/^root/{print $1"的uid是"$3}' /etc/passwd
2 . printf格式輸出 :
做用 : 能夠格式化(format)輸出 , 默認不換行
要點 : printf須要指定格式(format)
格式(format)是用來指定後面每一個item(條、項目)的輸出格式的
printf默認不會自動打印換行符,須要本身動手添加"\n"
printf默認沒有輸出字段分隔符
使用格式 : printf format itme1
format的指示符都是以%開頭的 , 後面跟一個字符 :
%s : 表示字符串
%d : 十進制整數
%f : 表示浮點數(float) , 也就是小數 (%4.2f 其中4表示總顯示寬度 , 2表示小數的尾數)
%x : (16進制) %o : (8進制)
修飾符 : %Ns N表示顯示寬度(是一個數字)
- : 表示左對齊 , 默認是右對齊
用法 : 例 格式化輸出/etc/passwd文件中的用戶名 , uid , gid 三列
awk -F: '{printf "%-15s %-5d %-5d\n",$1,$3,$4}' /etc/passwd
執行下面兩條語句看對比 :
echo -e 'hello\nwelcome\nlinux\n1234567890' | awk '{printf "%10s\n",$1}'
echo -e 'hello\nwelcome\nlinux\n1234567890' | awk '{printf "%8s\n",$1}'
六 . awk的比較表達式
比較表達式採用的的是關係運算符 , 用於比較數字與字符串 .
數字與字符串使用的運算符有 :
< 大於 <= 小於等於 = 賦值 == 相等 != 不相等 > 大於 >= 大於等於
例 : 打印 /etc/passwd 文件中的uid=0的帳號信息 (圖中命令沒有寫print , 是由於awk會默認執行print命令)
以冒號分隔打印/etc/passwd文件第七列爲 /bin/bash的行
七 . awk的匹配模式
/key/ #匹配key關鍵字
x ~ /key/ #匹配正則 , 其中key能夠是正則表達式 , x一般是$1~$n
(awk -F: '$1~/ro/{print $0}' /etc/passwd #打印/etc/passwd第一列包含ro字符的內容行)
x !~/key/ #不匹配正則
(awk -F: '$7 !~/nologin$/' /etc/passwd #打印/etc/passwd中第7列(即登陸shell)除了nologin結尾的用戶信息)
常見模式 :
1. 空模式 (例 : awk -F: '{print $1}' /etc/passwd #打印文件/etc/passwd第一列 , 不匹配)
2. 固定模式地址 (例 : awk -F: '$1~/^ro/{print $1}' /etc/passwd #打印第一列以ro開頭的第一列)
3. 範圍模式地址 (例 : awk -F: '/^ro/,/^lp/{print $1}' /etc/passwd #打印以ro開頭到lp開頭的第1列內容)
注 : awk中不支持行號定址 (反例 : awk -F: '2,5{print $1}' /etc/passwd) ;但用awk的內置變量NR就能夠實現相似行號定址的功能 ,如 : (awk 'NR==2,NR==5' /etc/passwd # 輸出/etc/passwd文件的第2行至第5行)
八 . 賦值運算
a++ #等同於 a=a+1
a+=5 #等於a=a+5
a+=$n #等同於a=a+$n
例 : 對 /etc/passwd 文件中的 uid 作累加計算
以上就是awk比較全面的介紹及如門操做 !!!