目錄
一、理論
1.awk原理
2.awk打印
?3.awk條件判斷
4.awk數(shù)組與循環(huán)
5.awk函數(shù)
6.常用命令
二、實驗
1.統(tǒng)計磁盤可用容量
2.統(tǒng)計/etc下文件總大小
3.CPU使用率
4.統(tǒng)計內(nèi)存
5.監(jiān)控硬盤
一、理論
1.awk原理
(1)概念
awk由 Aho,Weinberger 和 Kernighan 創(chuàng)建的文本模式掃描和處理語言。
awk非常復(fù)雜,所以這不是一個完整的指南,但應(yīng)該給你一個知道什么 awk 可以做。它使用起來比較簡單,強(qiáng)烈建議使用。
(2)基本格式
awk? [選項]? ?'處理模式或條件{處理動作}'??文件名
'{ }'為固定格式
(3)內(nèi)置變量
內(nèi)置變量,不能用雙引號括起來,不然系統(tǒng)會把它當(dāng)成字符串。
表1 內(nèi)置變量
內(nèi)置變量 | 功能 |
$0 | 當(dāng)前處理的行的整行內(nèi)容 ?打印所有 |
$n | 當(dāng)前處理行的第n個字段(第n列) |
NR | 當(dāng)前處理的行的行號(序數(shù)) |
NF | 當(dāng)前處理的行的字段個數(shù)。$NF代表最后一個字段 |
FS | 列分割符。指定每行文本的字段分隔符,輸入內(nèi)容的分隔符, 默認(rèn)為空格或制表位。與"-F"作用相同 用-F可以不加單引號 -F:,用FS必須用="" ? |
OFS | 輸出內(nèi)容的列分隔符,默認(rèn)為空格 |
ORS | 輸出記錄分隔符,默認(rèn)為換行符\n |
FILENAME | 被處理的文件名 |
RS | 行分隔符。awk從文件中讀取資料時, 將根據(jù)RS的定義把資料切割成許多條記錄,而awk一次僅讀入一條記錄進(jìn)行處理。默認(rèn)為換行符\n |
(4)處理動作
①基本格式:awk ?[選項] ? '處理模式或條件{處理動作}' 文件名
②print動作:打印,打印'{print $1}'即為打印第一列,'{print $n}'即打印為第n列,'{print $n,$m}'即為打印第n列和第m列。
③print打印順序:'BEGIN{print "1"} END {print ?"2"} ?{print "3"} ',首先打印BEGIN后的print 1,然后打印print 3 ?最后打印END后的print 2,BEGIN表示第一個打印,END表示最后打印
(5)選項
① 基本格式:awk? [選項]? ?'處理模式或條件{處理動作}'?文件名
② 選項若不寫默認(rèn)為以空格為分隔符處理,且會將空格自動壓縮。
③ -F 選項 指定分隔符,即指定以什么為分隔符處理內(nèi)容
注意一定是單引號:'模式或條件 {操作}'
{ }外指定條件,{ }內(nèi)指定操作。
表2 選項
選項 | 功能 |
-F | “分隔符” 指明輸入時用到的字段分隔符,默認(rèn)的分隔符是若干個連續(xù)空白符 |
-v(小v) | var=value 變量賦值 |
(6)處理模式
①基本格式:awk? [選項]? ?'處理模式或條件{處理動作}'?文件名
②處理模式為空表示無其他額外條件。
③正則表達(dá)式匹配模式
正則匹配:與正則表達(dá)式配合使用。
2.awk打印
(1)基本打印用法
① 基本打印
指定行號
打印行號和內(nèi)容
打印第3行
打印第3行到第5行
打印第3行和第5行
②奇偶行打?。?/p>
打印偶數(shù)
打印奇數(shù)
③awk運(yùn)算:
運(yùn)算
先打印行,再跳行(奇數(shù))
先跳行,再打?。ㄅ紨?shù))
(2)文件內(nèi)容匹配過濾
與正則表達(dá)式配合使用:
(3)BEGIN打印模式
格式:awk 'BEGIN{...};{...};END{...}' 文件
處理過程:
①?在awk處理指定的文本之前,需要先執(zhí)行BEGIN{...}模式里的命令操作
②?中間的{...} 是真正用于處理文件的命令操作
③?在awk處理完文件后才會執(zhí)行END{...}模式里的命令操作。END{ }語句塊中,往往會放入打印結(jié)果等語句。
BEGIN END模式
-v
(4)BEIGIN模式指定
BEGIN模式在awk執(zhí)行前改變分隔符,執(zhí)行過程中,以“:”分割,打印指定內(nèi)容
指定換行符
(5)awk的三元表達(dá)式
awk的三元表達(dá)式繼承了java的用法,格式與Java相似
格式:awk '(條件表達(dá)式)?(A表達(dá)式或者值):(B表達(dá)式或者值)'
三元表達(dá)式(面試):
將變量 max 設(shè)置為輸入行字段 3 和 4 之間的最大值。
? : 運(yùn)算符是 if-else 語句的簡寫,因此此行等效于 if ($3 >= $4) { max=$3 } else { max=$4 }
取比較結(jié)果的最大值,賦值給變量max,并且輸出max行的所有內(nèi)容,然后打印其中的1-6行;
(6)awk的精準(zhǔn)篩選
awk支持使用正則進(jìn)行模糊匹配,也支持字符串和數(shù)字的精確匹配,并且支持邏輯與和邏輯或
表2 條件匹配
比較符號 | 描述 |
// | 全行數(shù)據(jù)正則匹配 |
!// | 對全行數(shù)據(jù)正則匹配后取反 |
~// | 對特定數(shù)據(jù)正則匹配 |
!~// | 對特定數(shù)據(jù)正則匹配后取反 |
== | 等于 |
!= | 不等于 |
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
&& | 邏輯與,如A&&B,要求滿足A并且滿足B |
|| | 邏輯或,如A||B,要求滿足A或者滿足B |
表3?awk的精準(zhǔn)篩選
變量 | 功能 |
$n(> < ==) | 用于對比數(shù)值 |
$n~"字符串" | 代表第n個字段包含某個字符串 |
$n!~"字符串" | 代表第n個字段不包含某個字符串 |
$n=="字符串" | 代表第n個字段為某個字符串 |
$n!="字符串" | 代表第n個字段不為某個字符串 |
$NF | 代表最后一個字段 |
-F
小于等于10 uid
取反
(7)awk的分隔符用法
①?RS 指定行分隔符:
awk從文件中讀取資料時,將根據(jù)RS的定義把資料切割成許多條記錄,
而awk一次僅讀入一條記錄進(jìn)行處理。內(nèi)置變量RS的預(yù)設(shè)值是"\n" 也就是換行。
也可以使用BEGIN模式在操作前進(jìn)行行分隔符的改變。
②?指定輸出的分隔符:
OFS:輸出內(nèi)容的列分隔符。($n=$n用于激活,否則不生效,n必須存在)
對于輸出時改變分隔符,我們常用到tr,awk,它們都可以實現(xiàn)在輸出內(nèi)容改變原本的分隔符
③?awk改變輸出分隔符
精準(zhǔn)篩選
邏輯且
?3.awk條件判斷
(1)條件判斷打印
if判斷后面如果只有一個動作指令,則花括號{}可省略,如果if判斷后面的指令為多條指令則需要使用花括號括起來,多個指令使用分號分隔。
使用了if語句,內(nèi)部條件(),外部條件{},整個加{}作為一條語句執(zhí)行,相當(dāng)于嵌套語法
①單分支語法
if(判斷條件){
動作指令序列;
}
查找cpu使用率大于0.3的進(jìn)程:
ps -eo user,pid,pcpu,comm | awk '{if($3>0.5) print}'
②雙分支語法
if(判斷條件){
動作指令1;
} else {
動作指令2;
}
統(tǒng)計系統(tǒng)用戶與普通用戶的個數(shù):
awk -F: '{if($3<1000){x++} else{y++}} END{print "系統(tǒng)用戶個數(shù):"x"","普通用戶個數(shù):"y""}' /etc/passwd
③ 多分支語句
if(判斷條件){
動作指令1;
} else if(判斷條件2){
動作指令2;
} else {
動作指令N;
}
If條件:
4.awk數(shù)組與循環(huán)
?awk結(jié)合數(shù)組運(yùn)用
awk中定義數(shù)組打?。?/p>
①數(shù)組遍歷
語法:
for(變量 in 數(shù)組名){
動作指令序列
}
awk中的數(shù)組形成遍歷,處理文件去重統(tǒng)計:
Awk結(jié)合數(shù)組去重
出現(xiàn)幾次賦值幾次,把$1的值作為索引下標(biāo)
②for循環(huán)
采用與C語言一樣的語法格式
for(表達(dá)式1;表達(dá)式2;表達(dá)式3) {
動作指令序列
}
awk 'BEGIN{ for (i=1;i<=4;i++) {print i}}'
awk -F: '{ \
for(i=1;i<=NF;i++) \
> {if($i=="root") x++} \
> } END {print x}' /etc/passwd
③ while循環(huán)
語法:
while(條件判斷){
動作指令序列;
}
awk 'BEGIN{ i=1; while(i<=5) {print i;i++}}'
④ 中斷語句
與shell類似,awk提供了continue、break、exit循環(huán)中斷語句。
awk 'BEGIN{ \
i=0;
while(i<=5) { \
i++; \
if(i==3) {continue}; \
print i \
}; \
} \
END {print "END"}' /tmp/hosts
5.awk函數(shù)
(1)內(nèi)置I/O函數(shù)
①?getline
能讓awk立刻讀取下一行數(shù)據(jù)(讀取下一條記錄并復(fù)制給$0,并重新設(shè)置NF、NR和FNR).
#解決掛載邏輯卷時,分區(qū)信息跨行顯示的問題
df -h | awk '{if(NF==1) {getline;print $3}; if(NF==6) {print $4}}'
getline的工作過程:
1)當(dāng)getline左右無重定向符號(“<”,">")或者管道符號(“|”)時,
awk首先讀取的是第一行,而getline獲取的是光標(biāo)跳轉(zhuǎn)至下一行的內(nèi)容(也就是第二行)。
2)當(dāng)getline左右有管道符號或重定向符時,
getline則作用定向輸入文件,由于文件是剛打開,并沒有被awk讀入一行,
而只是getline讀入,所以getline返回的是文件的第一行,而不是跳轉(zhuǎn)至一行輸入
原因:getline運(yùn)行之后awk會改變NF,NR,$0,F(xiàn)NR等內(nèi)部變量,所以此時讀取$0的行號不再為1,而是2。
重定向:
getline 管道服 (賦值變量):
②?next函數(shù)
停止處理當(dāng)前的輸入記錄,立刻讀取下一條記錄并返回awk程序的第一個模式匹配重新處理數(shù)據(jù)。
有點(diǎn)類似于循環(huán)語句中的continue,不會執(zhí)行當(dāng)次循環(huán)的后續(xù)語句
awk -F: '/root/{getline;print "next line:",$0} {print "normal line"}' /etc/passwd
awk -F: '/root/{next;print "next line:",$0} {print "normal line"}' /etc/passwd
總結(jié):getline,會繼續(xù)執(zhí)行后續(xù)的指令print “next line:”,而next不會執(zhí)行后續(xù)指令,而是重新開始匹配。
③system(命令)函數(shù)
可以直接在awk中調(diào)用shell命令,會啟動一個新shell進(jìn)程執(zhí)行命令。
awk 'BEGIN{system("ls")}'
awk '{system("echo date:"$0)}' /tmp/hosts
(2)內(nèi)置數(shù)值函數(shù)
cos(expr)、sin(expr)、sqrt(expr)
int(expr)函數(shù)
可以對小數(shù)取整
awk 'BEGIN{print int(6.8)}'
6
rand()函數(shù)
返回0到1之間的隨機(jī)數(shù)
awk 'BEGIN{print rand()}'
awk 'BEGIN{for(i=1;i<=5;i++) print int(100*rand())}' #生成5個100以內(nèi)的隨機(jī)數(shù)
srand([expr])
可以使用expr定義新的隨機(jī)數(shù)種子,沒有expr時則使用當(dāng)前系統(tǒng)的時間為隨機(jī)數(shù)種子
awk 'BEGIN{srand();print rand()}' #使用時間做隨機(jī)數(shù)種子
awk 'BEGIN{srand(22);print rand()}' #使用數(shù)值做隨機(jī)數(shù)種子
(3)內(nèi)置字符串函數(shù)
length([s])函數(shù)
可以統(tǒng)計字符串s的長度,如果不指定字符串s則統(tǒng)計$0的長度
awk 'BEGIN{test="hello"; print length(test)}' #打印字符串長度
awk 'BEGIN{t[0]="hi";t[1]="the"; print length(t)}' #返回數(shù)組元素個數(shù)
awk '{print length()}' /etc/shells #返回文件每行的字符長度
index(字符串1,字符串2)
返回字符串2在字符串1中的位置
awk 'BEGIN{test="hello";print index(test,"l")}'
match(s,r)
根據(jù)正則表達(dá)式r返回其在字符串s中的位置坐標(biāo)
awk 'BEGIN{print match("How much","[a-z]")}' #小寫字母在第2個位置開始出現(xiàn)
2
tolower(srt)
可以將字符串轉(zhuǎn)換為小寫
awk 'BEGIN{print tolower("HELLo")}'
hello
toupper(str)
將字符串轉(zhuǎn)為大寫
split(字符串,數(shù)組,分隔符)
將字符串按特定的分隔符切片后存儲在數(shù)組中,如果沒指定分隔符,則使用IFS定義的。
數(shù)組下標(biāo)從1開始
awk 'BEGIN{split("hello world",test); print test[1],test[2]}'
awk 'BEGIN{split("hello:world",test,":"); print test[1],test[2]}' #指定冒號(:)為分隔符
gsub(r,s,[,t])
將字符串t中所有與正則表達(dá)式r匹配的字符串全部替換為s,如果沒有指定字符串t,則默認(rèn)對$0進(jìn)行替換操作
head -1 /etc/passwd | awk '{gsub("[0-9]","**");print $0}'
root:x:**:**:root:/root:/bin/bash
sub(r,s,[,t])
與gsub類似,但僅替換第一個匹配的字符串,而不是替換全部
substr(s,i,[,n])
對字符串s進(jìn)行截取,從第i位開始,截取n個字符串,如果n沒有指定則一直截取到字符串s的末尾位置
awk 'BEGIN{hi="Hello World"; print substr(hi,2,3)}' #從第2位開始截取3個字符
ell
(4)內(nèi)置時間函數(shù)
systime()
返回當(dāng)前時間距離1970-01-01 00:00:00有多少秒
awk 'BEGIN{print systime()}'
(5)用戶自定義函數(shù)
語法:
function 函數(shù)名(參數(shù)列表) { 命令序列 }
awk ' \
function max(x,y) { \
if(x>y) {print x} \
else {print y} } \
BEGIN {max(5,6)} '
6.常用命令
cat example.txt | awk 'NR%2==1' #刪除example.txt文件中的所有偶數(shù)行
echo " false" |awk -F' ' '{print $NF}' #去掉前面的空格
docker images | grep 'mysql' | awk '{printf"%s:%s\n",$1,$2}' #獲取鏡像名:Tag
ps -ef | grep java | grep -v 'color' awk '{for (i=8;i<=NF;i++)printf("%s ", $i);print ""}' #獲取從第八列開始到最后一列的內(nèi)容
二、實驗
1.統(tǒng)計磁盤可用容量
(1)運(yùn)行結(jié)果
2.統(tǒng)計/etc下文件總大小
(1)運(yùn)行結(jié)果
3.CPU使用率
(1)運(yùn)行結(jié)果
4.統(tǒng)計內(nèi)存
(1)腳本截圖
(2)運(yùn)行結(jié)果
5.監(jiān)控硬盤
(1)腳本截圖
(2)運(yùn)行結(jié)果
文章來源:http://www.zghlxwxcb.cn/news/detail-474965.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-474965.html
到了這里,關(guān)于Shell腳本攻略:文本三劍客之a(chǎn)wk的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!