1. 程式人生 > >shell編程awk進階

shell編程awk進階

xfs gin AD eat ces rand access wap swa

awk操作符

算術操作符: x+y, x-y, x*y, x/y, x^y, x%y -x: 轉換為負數 +x: 轉換為數值

字符串操作符:沒有符號的操作符,字符串連接

賦值操作符: =, +=, -=, *=, /=, %=, ^= ++, --

比較操作符: ==, !=, >, >=, <, <=

awk -F: ‘!($3==0) {print $1}‘ /etc/passwd

模式匹配符: ~ 左邊是否和右邊匹配包含 !~ 是否不匹配

awk –F: ‘$0 ~ /root/{print $1}‘ /etc/passwd

awk –F: ‘$3==0’ /etc/passwd

awk正則匹配表達式

(1)如果未指定:空模式,匹配每一行

(2) /regular expression/:僅處理能夠模式匹配到的行,需要用/ /括起來

awk ‘/^UUID/{print $1}‘ /etc/fstab

(3) relational expression: 關系表達式,結果為“真”才會被處理

awk ‘!0’ /etc/passwd

(4) line ranges:行範圍

startline,endline:/pat1/,/pat2/ 不支持直接給出數字格式

awk -F: ‘/^root\>/,/^nobody\>/{print $1}‘ /etc/passwd

(5) BEGIN/END模式

BEGIN{}: 僅在開始處理文件中的文本之前執行一次 END{}:僅在文本處理完成之後執行一次

awk控制語句

if-else while循環 do-while循環 for循環 switch語句 break和continue

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

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

awk 自帶對文件行內容的循環,awk使用循環一般是對切割數據列進行循環操作

awk 的基本格式 awk -F: ‘{}‘ filepath

性能比較

time (awk ‘BEGIN{ total=0;for(i=0;i<=10000;i++){total+=i;};print total;}‘)

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

time(for ((i=0;i<=10000;i++));do let total+=i;done;echo $total)

time(seq –s ”+” 10000|bc)

awk數組

默認是關聯數組

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

for(var in array) {for-body} 註意:var會遍歷array的每個索引

awk函數

數值處理:

rand():返回0和1之間一個隨機數 awk ‘BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }‘

字符串處理:

echo $a | awk -F "" ‘{for(i=1;i<=NF;i++){if($i ~ /^[0-9]+$/) printf"%s", $i}}‘

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(/:/,“-",$0)‘

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

netstat -tan | awk ‘/^tcp\>/{split($5,ip,":");count[ip[1]]++} END{for (i in count) {print i,count[i]}}‘

自定義函數

awk中調用shell命令

system命令

空格是awk中的字符串連接符,如果system中需要使用awk中的變量可以使用 空格分隔,或者說除了awk的變量外其他一律用""引用起來。

awk BEGIN‘{system("hostname") }‘ awk BEGIN‘{system("ifconfig") }‘

awk ‘BEGIN{score=100; system("echo your score is " score) }‘

awk傳遞值給shell循環,shell命令不能直接在awk的action中執行

技術分享圖片
#!/bin/bash
awk /^[0-9]/{ip[$1]++}END{for(i in ip){if(ip[i]>30) print i}} access_log | while read ip; do
      echo $ip
done 
View Code

awk腳本

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

向awk腳本傳遞參數

格式: awkfile var=value var2=value2... Inputfile

註意:在BEGIN過程中不可用.直到首行輸入完成以後,變量才可用.可以通 過-v 參數,讓awk在執行BEGIN之前得到變量的值.

命令行中每一個指定的變 量都需要一個-v參數

awk實例

技術分享圖片
 1 awk {for(i=1;i<=NF;i++){word[$i]++}}END{for(j in word){print j,word[j]}} /etc/rc.sysinit
 2 
 3 [root@centos7 ~]# awk {if($NF=="m"){sum_m+=$2;num_m++} else{sum_f+=$2;num_f++}}END{printf "male:%.2f\nfemale:%.2f\n",sum_m/num_m,sum_f/num_f} score
 4 male:99.50
 5 female:95.00
 6 [root@centos7 ~]# awk {pcount[$3]++;s[$3]+=$2}END{for(i in pcount){print i, pcount[i],s[i]/pcount[i]}} score
 7 m 2 99.5
 8 f 2 95
 9 [root@centos7 ~]# echo "2008:08:08 :08" | awk sub(/:/,"-",$1)
10 2008-08:08 :08
11 [root@centos7 ~]# echo "2008:08:08 :08" | awk gsub(/:/,"-",$1)
12 2008-08-08 :08
13 [root@centos7 ~]# echo "2008:08:08:08" | awk gsub(/:/,"-",$1)
14 2008-08-08-08
15 [root@centos7 ~]# head -n1 /etc/passwd | awk {split($0,arr,":")}END{for(i in arr){print i,arr[i]}}
16 4 0
17 5 root
18 6 /root
19 7 /bin/bash
20 1 root
21 2 x
22 3 0
23 [root@centos7 ~]# netstat -an |awk /^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}
24 192.168.33.1 2
25 0.0.0.0 5
View Code 技術分享圖片
 1 awk -F: -v i=0 i{print $0} /etc/fstab
 2 [root@centos7 ~]# awk /^[^#]/ /etc/fstab
 3 UUID=1ec9c7b3-bec1-4998-9aad-057423419431 /                       xfs     defaults        0 0
 4 UUID=df74adc0-09cd-4a97-a1e4-9f0d4a4b5796 /boot                   xfs     defaults        0 0
 5 UUID=bacf4f88-3be9-4e74-ba5b-90274a2099ab /data                   xfs     defaults        0 0
 6 UUID=339ab167-206a-4210-a36d-8d575579959e swap                    swap    defaults        0 0
 7 [root@centos7 ~]# awk /^ *#/ /etc/fstab
 8 #
 9 # /etc/fstab
10 # Created by anaconda on Wed Mar 28 01:53:52 2018
11 #
12 [root@centos7 ~]# awk -F: /\/bin\/bash$/{print $1,$NF} /etc/passwd
13 root /bin/bash
14 yanxianghui /bin/bash
15 tomcat /bin/bash
16 [root@centos7 ~]# awk -F: /^root\>/,/^mail\>/{print $1} /etc/passwd
17 root
18 [root@centos7 ~]# df -h | awk -F% $0 ~ /^\/dev\/sd/{print $1}| awk $5>=10
19 /dev/sda1      1014M  194M  821M  20
20 [root@centos7 ~]# df -h | awk -F% $0 ~ /^\/dev\/sd/{print $1}
21 /dev/sda2        50G  4.2G   46G   9
22 /dev/sda3        30G   82M   30G   1
23 /dev/sda1      1014M  194M  821M  20
View Code 技術分享圖片
1 [root@centos7 ~]# awk /^[0-9]/{ip[$1]++}END{for (i in ip){print i,ip[i]}} access_log 
2 172.20.101.111 2
3 172.20.101.238 19
4 172.20.101.188 6
View Code

shell編程awk進階