第八周總結

AWK高級用法

awk控制語句

?{ statements;… } 組合語句

?if(condition) {statements;…}

?if(condition) {statements;…} else {statements;…}

?while(conditon) {statments;…}

?do {statements;…} while(condition)

?for(expr1;expr2;expr3) {statements;…}

?break

?continue

?delete array[index]

?delete array

?exit

?

awk控制語句if-else

? 語法:if(condition){statement;…}[else statement]? 單分支[及雙分支]

if(condition1){statement1}else if(condition2){statement2}

else{statement3}?? 多分支

? 使用場景:對awk取得的整行或某個字段做條件判斷

? 示例:

awk -F: ‘{if($3>=1000)print $1″:”$3}’ /etc/passwd?? 顯示第八周總結

awk -F: ‘{if($NF==”/bin/bash”)print $1}’ /etc/passwd? 只顯示最后一個字段是/bin/bash的行的第一個字段

第八周總結

awk ‘{if(NF>5)print $0}’ /etc/fstab? 意思是只顯示每行字段數大于5的行

awk -F: ‘{if($3>=1000){printf “common user:%s\n”,$1}else{printf “root or sysuser:%s\n”,$1}}’ /etc/passwd?

對每行進行判斷,如果uid大于等于1000,則顯示common user ,否則顯示root or sysuse

第八周總結

?

awk -F: ‘{if($3>=1000) printf “Common user: %s\n”,$1; else printf “root or Sysuser: %s\n”,$1}’ ?/etc/passwd? 注意:如果ifelse后面只有一條語句,可以不寫大括號,但是如果后面跟多條語句必須寫大括號,建議寫大括號!

df -h|awk -F% ‘/^\/dev\/sd/{print $1}’|awk ‘$NF>=80{print $1,$5}’

意思是如果分區利用率大于80,則顯示分區名及分區利用率。

awk ‘BEGIN{test=100;if(test>90){print “very good”}else if(test>60){print “good”}else{print “no pass”}}’? 顯示第八周總結

?

awk控制語句

?while循環 ?(對行里的字段進行循環,awk自帶行循環功能)

?語法:while(condition){statement;…}

?條件,進入循環;條件,退出循環

?使用場景:

對一行內的多個字段逐一類似處理時使用

對數組中的各元素逐一處理時使用

?示例:

awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF){{print $i,length($i)};i++}}’ /etc/grub2.cfg? 顯示linux16那一行的每個字段及每個字段的長度

^[[:space:]]* 意思是以空格開頭,空格可有可無

第八周總結

awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF){if(length($i)>=10){print $i,length($i)};i++}}’ /etc/grub2.cfg

意思是顯示linux16那一行中,字段長度大于等于10的字段及字段長度

第八周總結

?

awk ‘BEGIN{print length(“dadsad”)}’? 顯示字符串的長度,必須使用雙引號引上!

awk ‘BEGIN{print length(“dadsad我們“)}’? 顯示8

?

awk控制語句

?do-while循環

?語法:do{statement;…}while(condition)do{循環體}while(條件)

?意義:無論真假,至少執行一次循環體

?示例:用awk方式實現1+2+3+..100

方法一:

?awk ‘BEGIN{total=0;i=0;do{total+=i;i++;}while(i<=100);print total}’

方法二:awk ‘BEGIN{i=1;while(i<=100){sum=sum+i;i++};print sum}’ 或者

awk ‘BEGIN{i=1;while(i<=100){sum=sum+i;i++};{print sum}}’

?

awk控制語句

?for循環

?語法:for(expr1;expr2;expr3) {statement;…}

?常見用法:for(variable assignment;condition;iteration process)

{for-body}

?特殊用法:能夠遍歷數組中的元素

語法:for(var in array) {for-body}

?示例:

awk ‘/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){print $i,length($i)}}’ /etc/grub2.cfg

第八周總結

例題:用awkfor循環方式實現1+2+3+..100

awk ‘BEGIN{for(i=1;i<=100;i++){sum=sum+i};{print sum}}’

注意:在awk語句內的變量,在awk語句結束后就消失了,與bash不同?。?!

?

性能比較

?time (awk ‘BEGIN{ total=0;for(i=0;i<=1000000;i++){total+=i;};print total;}’)? 效率最高

?time(total=0;for i in {1..1000000};do total=$(($total+i));done;echo $total)

?time(for ((i=0;i<=1000000;i++));do let total+=i;done;echo $total)效率最低

? time(seq -s + 1000000 | bc)

awk控制語句

?switch語句

?語法:switch(expression) {case VALUE1 or /REGEXP/:statement1; case

VALUE2 or /REGEXP2/:statement2; …; default:statementn}? 注意格式冒號

switch后面跟的表達式如果等于VALUE1 or /REGEXP/,則執行statement1,如果等于VALUE2 or /REGEXP2/,則執行statement2,如果都不等于,則執行statementn

?breakcontinue

?awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}’? 顯示奇數和

awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}’

意思是當加到66時結束循環(break

練習:計算1+2+3+..100中的奇數和及偶數和

奇數和:? 顯示2500

awk ‘BEGIN{for(i=1;i<=100;i++){if(i%2==0){continue}else{sum=sum+i}}

print sum}’

偶數和:顯示2550

awk ‘BEGIN{for(i=1;i<=100;i++){if(i%2==1){continue}else{sum=sum+i}};

print sum}’

?

awk控制語句

?break [n]

?continue [n]

?next:

提前結束對本行處理而直接進入下一行處理(awk自身循環)

awk -F: ‘{if($3%2!=0) next; print $1,$3}’ /etc/passwd或者

awk -F: ‘{if($3%2!=0) next; {print $1,$3}}’ /etc/passwd

意思是如果第三列是奇數,則不做任何處理,直接進入下一行,說白了就是顯示第三列是偶數行的第一和第三字段

第八周總結

?

awk -F: ‘{if($3>10){print $1,$3};if($3<100){print $1,$3}}’ /etc/passwd

注意:這樣寫,分號兩側的語句是邏輯或的關系!這條代碼的意思是顯示全部行的$1$3

awk -F: ‘{if($3>10&&$3<100){print $1,$3}}’ /etc/passwd

這樣寫才能實現并且的邏輯關系,顯示$3大于10小于100的行的$1$3

第八周總結

?

awk數組(awk中數組就是關聯數組,沒有普通數組的說法)

?關聯數組:array[index-expression]

?index-expression:

?(1) 可使用任意字符串;字符串要使用雙引號括起來

?(2) 如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其值

初始化為“空串”!

?若要判斷數組中是否存在某元素,要使用“index in array”格式進行遍歷,index代表下表變量,array代表數組名稱!

?示例:

?weekdays[“mon”]=”Monday”?? awk中給數組賦值的方式,雙引號必須加

?awk ‘BEGIN{weekdays[“mon”]=”Monday”;weekdays[“tue”]=”Tuesday”;

print weekdays[“mon”]}’

?awk ‘!arr[$0]++’ f1

去掉重復行!

?awk ‘{!arr[$0]++;print $0, arr[$0]}’ f1

第八周總結

例如:為數組賦值并打印

awk ‘BEGIN{title[“ceo”]=”mage”;tile[“coo”]=”zhangsir”;{print title[“ceo”]}}’

顯示第八周總結

例如:vim f1

第八周總結

awk ‘!arr[$0]++’ f1

!arr[$0]++的意思是先對arr[$0]取反,同時arr[$0]=arr[$0]+1

邏輯是:

當第一行讀入,arr[“aaa”]= “”,

此時!arr[“aaa”]=1,arr[“aaa”]=arr[“aaa”]+1=””+1=1,說明arr[“aaa”]=1,

!arr[“aaa”]=1為真,真則執行后面隱藏掉的print $0,打印第一行。

第二行、第三行的執行結果同第一行

第四行時,arr[“aaa”]=1,!arr[“aaa”]=0,為假,則不執行print $0,但arr[“aaa”]=1+1=2

說白了,這個命令的意思是去掉重復行!

sort -u f1 這個命令也可以去重!

awk ‘!++arr[$0]’ f1? 什么都不打印

邏輯是第一行讀入時arr[“aaa”]=””,先執行++arr[“aaa”],則

arr[“aaa”]=””+1=1,取反則為0,假,則不執行print $0,以此類推

?

awk數組

?若要遍歷數組中的每個元素,要使用for循環

?for(var in array) {for-body}

?注意:var會遍歷array的每個索引

?示例:

?awk ‘BEGIN{weekdays[“mon”]=”Monday”;weekdays[“tue”]

=”Tuesday”;for(i in weekdays) {print weekdays[i]}}‘

?netstat -tan | awk ‘/^tcp/{state[$NF]++}END

{for(i in state) { print i,state[i]}}’

?awk ‘{ip[$1]++}END{for(i in ip) {print i,ip[i]}}’ /var/log/httpd/access_log

?

練習:運用for遍歷來打印數組元素!

awk ‘BEGIN{title[“ceo”]=”mage”;title[“coo”]=”zhangsir”;

title[“cto”]=”wang”;for(i in title){print title[i]}}’? 顯示如圖

第八周總結

練習:

systemctl start httpd

netstat -nat

第八周總結

ab -c 100 -n 2000 http://192.168.30.7:9527/? 并發訪問

bc命令需要安裝包yum install httpd-tools

第八周總結

如果想統計每種狀態有多少次,如何實現?

netstat -tan | awk ‘/^tcp/{state[$NF]=state[$NF]+1}END{for(i in state){print i,state[i]}}’

第八周總結

例如:統計/var/log/httpd/access_log哪些ip在訪問,分別訪問了多少次?

cat access_log | awk ‘/^[0-9]+/{ip[$1]=ip[$1]+1}END{for(i in ip){print i,ip[i]}}’

第八周總結

例如:編寫腳本,分析上題結果,凡連接數超過1000的地址,將其放入防火墻中:

iptables -A INPUT -s 172.20.111.65 -j REJECT 172.20.111.65扔到防火墻里

答:方法一:cat access_log | awk ‘/^[0-9]+/{ip[$1]=ip[$1]+1}END

{for(i in ip){if(ip[i]>10000){print i}}}’ | while read line;do iptables -A INPUT -s $line -j REJECT;done

查詢將哪些地址放入防火墻內:iptables -vnL

清空防火墻內的地址:iptables -F

方法二:cat access_log | awk ‘/^[0-9]+/{ip[$1]=ip[$1]+1}END{for(i in ip){print i,ip[i]}}’ | awk ‘{if($2>=1000){system(” iptables -A INPUT -s ” $1 ” -j REJECT “)}}’

例如:顯示上題中連接數排名前十的ip地址

cat access_log | awk ‘/^[0-9]+/{ip[$1]=ip[$1]+1}END{for(i in ip){print i,ip[i]}}’ | sort -k 2 -nr | head

注意:sort -k 2 -nr意思是按第二列的數字排序,而且是倒序!

例如:統計文檔/etc/rc.sysinit內每個單詞及出現的次數 基本格式awk ‘{}END{}’

awk ‘{for(i=1;i<=NF;i++){word[$i]=word[$i]+1}}END{for(j in word){print j,word[j]}}’ /etc/rc.sysinit

例如:有一個成績表,格式是姓名、分數、性別,如下圖

第八周總結

統計男生的平均成績和女生的平均成績?

awk ‘{if($3==”m”){sum_m=sum_m+$2;num_m=num_m+1}else{sum_f=sum_f+$2;

num_f=num_f+1}}END{printf “male:%.2f\nfemale:%.2f\n”,sum_m/num_m,

sum_f/num_f}’ score.txt

注意:下圖寫法不對,END內語句如果不遍歷,那么是不能引用數組的?。?!

第八周總結

用數組寫

awk ‘{sum[$3]=sum[$3]+$2;num[$3]=num[$3]+1}END{for(i in num){

print i,sum[i]/num[i]}}’ score.txt

?

awk函數(引用函數的時候必須帶小括號!)

? 數值處理:

rand():返回01之間的一個隨機數,說是隨機數,但實際上是一個固定的0.237788,如果想生成0-1的任何一個隨機數,需要借助srand()這個種子才可以.

例如:awk ‘BEGIN{print rand()}’? 只顯示0.237788

awk ‘BEGIN{srand();print rand()}’? 才能實現0-1之間的隨機數

awk ‘BEGIN{srand();print int(rand()*100)}’ 顯示100之內隨機的整數

awk ‘BEGIN{srand();for(i=1;i<=100;i++){print int(rand()*100)}}’

意思是顯示100100以內的隨機整數 ?注意:srand()函數就不能往for里面放,只能放BEGIN后面!

? 字符串處理:

?length([s]):返回指定字符串的長度

?sub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并將第一個匹配的內容替換為s

echo “2008:08:08 08:08:08″ | awk ‘sub(/:/,”-“,$1)’ 第八周總結

gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并全部替換為s所表示的內容

echo “2008:08:08 08:08:08″ | awk ‘gsub(/:/,”-“,$1)’ 第八周總結

split(s,array,[r]):以r為分隔符,切割字符串s,并將切割后的結果保存至array所表示的數組中,第一個索引值為1,第二個索引值為2,…

netstat -tan | awk ‘/^tcp\>/{split($5,ip,”:”);conut[ip[1]]=conut[ip[1]]+1}

END{for(i in conut){print i,count[i]}}’

例如head -n1 /etc/passwd | awk ‘{split($0,arr,”:”)}END{for(i in arr){print i,arr[i]}}’

第八周總結

?

awk函數

? 自定義函數

? 格式:

function 函數名 (參數1,參數2..參數N{

?? 語句

?? return 表達式

}

function name ( parameter, parameter, … ) {

statements

return expression

}

? 示例:

cat fun.awk

function max(v1,v2) {

v1>v2?var=v1:var=v2

return var

}

BEGIN{a=3;b=2;print max(a,b)}

awk –f fun.awk? 顯示的是3

或者

cat fun.awk

function max(v1,v2) {

v1>v2?var=v1:var=v2

return var

}

BEGIN{print max(a,b)}

awk -v a=100 -v b=200–f fun.awk? 顯示的是200

?

awk中調用shell命令

?system命令

?空格是awk中的字符串連接符,如果system中需要使用awk中的變量可以使用

空格分隔,或者說除了awk的變量外其他一律用“”引用起來。

awk BEGIN'{system(“hostname”)}’

awk ‘BEGIN{score=100; system(“echo your score is ” score) }’

注意:后面的的雙引號之前有一個空格!

awk腳本

?awk程序寫成腳本,直接調用或執行

?示例:

cat f1.awk

{if($3>=1000)print $1,$3}

awk -F: -f f1.awk /etc/passwd

或者vim f2.awk

#!/bin/awk –f

#this is a awk script

{if($3>=1000)print $1,$3}

chmod +x f2.awk

f2.awk –F: /etc/passwd

?

?

?

?

?

awk腳本傳遞參數

?格式:

awkfile var=value var2=value2… Inputfile

?注意:在BEGIN過程中不可用。直到首行輸入完成以后,變量才可用??梢酝?/span>

-v 參數,讓awk在執行BEGIN之前得到變量的值。命令行中每一個指定的變

量都需要一個-v參數(建議都加-v選項,-v具有通用性)

?示例:

cat test.awk

#!/bin/awk –f

{if($3 >=min && $3<=max)print $1,$3}

chmod +x test.awk

test.awk -F: -v min=100 -v max=200 /etc/passwd

練習:提取出字符串Yd$C@M05MB%9&Bdh7dq+YVixp3vpw中的所有數字

echo “Yd$C@M05MB%9&Bdh7dq+YVixp3vpw” | awk ‘gsub(/[^0-9]/,””,$0)’或者

echo “Yd$C@M05MB%9&Bdh7dq+YVixp3vpw” | awk ‘gsub(/[^[:digit:]]/,””,$0)’

注意:正則表達式里排除數字[^0-9]或者[^[:digit:]][^[0-9]]寫法錯誤

練習

解決DOS攻擊生產案例:根據web日志或者或者網絡連接數,監控當某個IP

并發連接數或者短時內PV達到100,即調用防火墻命令封掉對應的IP,監控頻

率每隔5分鐘。防火墻命令為:iptables -A INPUT -s IP -j REJECT

并發連接數使用netstat -nt 查看,通過web日志是使用命令

cat /var/log/httpd/access_log

本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/98994

(0)
柳寶玉柳寶玉
上一篇 2018-05-20
下一篇 2018-05-20

相關推薦

  • ansible的使用

    運維自動化發展歷程及技術應用 IAAS基礎設置即服務,提供硬件服務 PAAS平臺即服務,提供操作系統服務 SAAS軟件即服務,提供整套服務   ansible的安裝 yum -y install ansible ansible –version 查看版本信息   /etc/ansible/ansible.cfg? 配置文件 /…

    2018-06-04
  • mysql數據庫三:

    用戶權限管理和訪問限制,數據庫的鎖定;索引和日志

    2018-06-09
  • 自制mini的Linux系統

    如何打造一個小的Linux系統。這個可以當做一個很簡單的啟動盤,并使它能夠成功啟動且能有簡單的shell環境。

    Linux筆記 2018-05-11
  • N30-Listen學習匯總

    1.描述計算機的組成及其功能 計算機由CPU,存儲器,I/O設備等部件組成計算機,每一部件分別按要求執行特定的基本功能。 ? ? CPU包含運算器、控制器以及寄存器,其中運算器主要是對數據進行各種運算;而控制器是整個計算機系統的控制中心,負責指揮計算機各部分協調地工作,保證計算機按照預先規定的目標和步驟有條不紊地進行操作及處理;寄存器則用來保存指令執行過程中…

    2018-05-13
  • LInux系統故障模擬實驗:破壞了/boot/下的initramfs-3.10.0-693.el7.x86_64.img和vmlinuz-3.10.0-693.el7.x86_64文件

    /boot/initramfs-VERSION.img 和/boot/vmlinuz-VERSION兩個文件是linux系統內核啟動最核心的兩個文件,如果破壞,系統將難以啟動,本文將描述挽救方法,實驗環境Centos7.4 ;實驗環境 將boot下文件全部刪除(不包括目錄)重啟機器。

    2018-05-07
  • CentOS6和5啟動流程

    簡述過程

    2018-05-20
欧美性久久久久