簡述awk命令及用法
AWK是一種處理文本文件的語言,是一個強大的文本分析工具。
語法
awk [options]'program' {filenames}
參數
-F:指明輸入時用到的字段分隔符,默認是空格符
-v var=value: 自定義變量
program
program: PATTERN{ACTION STATEMENTS}
語句之間用分號分隔
- print
- 格式 :print item1,item2,….
$0:表示整個當前行 $1:每行第一個字段 NR:number of record, 總行數; NF:number of field,字段數量 {print NF}:打印每行的字段 {print $NF}:打印第NF個字段值(最后一個字段的值) FNR:單個數據文件處理的行數 \t:制表符 \n:換行符
- 實例
- F & $0
#輸出整行,awk {print} /etc/passwd = awk '{print $0}' /etc/passwd~]# awk {print} /etc/passwd~]# awk '{print $0}' /etc/passwdroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologin#":"為分格符輸出第一個字符~]# awk -F":" '{print $1}' /etc/passwdrootbindaemon#$1與$3相連輸出,不分隔~]# awk -F":" '{print $1 $3}' /etc/passwd root0bin1daemon2#多了一個逗號,$1與$3使用空白分格分隔~]# awk -F":" '{print $1,$3}' /etc/passwdroot 0bin 1daemon 2#$1與$3使用分格符分隔,自定義分隔符~]# awk -F":" '{print $1 "," $3}' /etc/passwdroot,0bin,1daemon,2 ~]# awk -F":" '{print $1 "-" $3}' /etc/passwdroot-0bin-1daemon-2 #自定義輸出內容~]# awk -F":" '{print "Username:" $1" \t Uid:" $3 }' /etc/passwdUsername:root Uid:0Username:bin Uid:1
- NF
#顯示每行有多少字段~]# awk -F: '{print NF}' /etc/passwd 777#將每行第NF個字段的值打印出來 ~]# awk -F: '{print $NF}' /etc/passwd/bin/bash/sbin/nologin/sbin/nologin#只輸出字段數=7的行~]# awk -F":" 'NF==7 {print }' /etc/passwdroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologin#輸出字段數>2的行~]# awk -F":" 'NF>2{print $0}' /etc/passwdroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologin
- NR
#輸出每行的行號localhost ~]# awk '{print NR,$0}' /etc/passwd 1 root:x:0:0:root:/root:/bin/bash2 bin:x:1:1:bin:/bin:/sbin/nologin3 daemon:x:2:2:daemon:/sbin:/sbin/nologin#顯示第5行localhost ~]# awk -F: 'NR==5{print}' /etc/passwd lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin#顯示5行以后的數據,并在前面顯示行號localhost ~]# awk -F: 'NR>5{print NR ,$0}' /etc/passwd 6 sync:x:5:0:sync:/sbin:/bin/sync7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown8 halt:x:7:0:halt:/sbin:/sbin/halt.....#顯示5行和第8行,并在前面顯示行號localhost ~]#awk -F: 'NR==5 || NR == 8 {print NR ,$0}' /etc/passwd 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin8 halt:x:7:0:halt:/sbin:/sbin/halt
- FNR&NR
localhost tmp]# cat data3hellohellohellolocalhost tmp]# awk '{print $0 ,"\t""FNR="FNR,"NR="NR}' data3 data3hello FNR=1 NR=1hello FNR=2 NR=2hello FNR=3 NR=3hello FNR=1 NR=4hello FNR=2 NR=5hello FNR=3 NR=6
- F & $0
- 格式 :print item1,item2,….
- 格式化打印printf
printf FORMAT, item1, item2, ... (1) FORMAT必須給出; (2) 不會自動換行,需要顯式給出換行控制符,\n (3) FORMAT中需要分別為后面的每個item指定一個格式化符號;
- 格式符:
%c: 顯示字符的ASCII碼;%d, %i: 顯示十進制整數;%e, %E: 科學計數法數值顯示;%f:顯示為浮點數;%g, %G:以科學計數法或浮點形式顯示數值;%s:顯示字符串;%u:無符號整數;%%: 顯示%自身;
- 修飾符
#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點后的精度;-: 左對齊+:顯示數值的符號
- 說明
(1). 可以在"%"和字母之間插進數字表示最大場寬。 例如:%3d 表示輸出3位整型數, 不夠3位右對齊。 %9.2f 表示輸出場寬為9的浮點數, 其中小數位為2, 整數位為6,小數點占一位, 不夠9位右對齊。 %8s 表示輸出8個字符的字符串, 不夠8個字符右對齊。 如果字符串的長度、或整型數位數超過說明的場寬, 將按其實際長度輸出.但對浮點數, 若整數部分位數超過了說明的整數位寬度, 將按實際整數位輸出;若小數部分位數超過了說明的小數位寬度, 則按說明的寬度以四舍五入輸出.另外, 若想在輸出值前加一些0, 就應在場寬項前加個0。 例如: %04d 表示在輸出一個小于4位的數值時, 將在前面補0使其總寬度為4位。 如果用浮點數表示字符或整型量的輸出格式, 小數點后的數字代表最大寬度,小數點前的數字代表最小寬度。 例如: %6.9s 表示顯示一個長度不小于6且不大于9的字符串。若大于9, 則第9個字符以后的內容將被刪除。(2). 可以在"%"和字母之間加小寫字母l, 表示輸出的是長型數。 例如: %ld 表示輸出long整數 %lf 表示輸出double浮點數 (3). 可以控制輸出左對齊或右對齊, 即在"%"和字母之間加入一個"-" 號可說明輸出為左對齊, 否則為右對齊。 例如: %-7d 表示輸出7位整數左對齊 %-10s 表示輸出10個字符左對齊
- 實例
#%d 顯示十進制整數~]# echo "1.7 2.52" | awk '{printf ("%d\n",$2)}'2#%f 顯示浮點數 ~]# echo "1.7 2.52" | awk '{printf ("%f\n",$1)}'1.700000#四舍五入輸入整數~]# echo "1.5" | awk '{printf ("%.f\n",$1)}' 2echo "1.4" | awk '{printf ("%.f\n",$1)}' 1#以3位長度、1位小數,"."占一位,浮點換行輸出第2個域(四舍五入)~]# echo "1.7 2.52" | awk '{printf ("%3.1f\n",$2)}'2.5#以6位長度,其中整數占2位,不足2位空格補足,“.”占一位,小數占3位,不足3位用0補足~]# echo "1.7 2.52" | awk '{printf ("%6.3f\n",$2)}'2.520#指數形式的浮點數輸出~]# echo "1.7 2.52" | awk '{printf ("%e\n",$1)}'1.700000e+00#用0補充格式~]# echo "123 1" | awk '{printf("%d\t%03d\n",$1,$2)}'123 001
- 格式符:
- BEGIN/END模式
BEGIN{}: 僅在開始處理文件中的文本之前執行一次;END{}:僅在文本處理完成之后執行一次;
- 實例
#開頭顯示“The data of passwd”localhost ~]# awk 'BEGIN{print "The data of passwd"} {print}' /etc/passwdThe data of passwdroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologin#顯示第一行,并在開頭和末尾顯示“The data of passwd”localhost ~]# awk 'BEGIN{print "print /etc/passwd"} NR==1{print} END{print "print /etc/passwd"}' /etc/passwdprint /etc/passwdroot:x:0:0:root:/root:/bin/bashprint /etc/passwd
- 實例
- 使用變量
- 內建變量:字段和記錄分隔符變量
FS:input field seperator,輸入字段分隔符,默認為空白字符OFS:output field seperator,輸出字段分隔符, 默認空白字符;RS:input record seperator,輸入時的換行符;ORS:output record seperator,輸出時的換行符;FIELDWIDTHS:指定列
- 實例
- FS&OFS
#自定義分輸入隔符為“:”localhost ~]#awk 'BEGIN{FS=":"} NR<4{print $1,$2,$3}' /etc/passwdroot x 0bin x 1daemon x 2#自定義分輸入隔符為“:”,輸出分隔符為“-”localhost ~]# awk 'BEGIN{FS=":" ;OFS="-"} NR<4{print $1,$2,$3}' /etc/passwdroot-x-0bin-x-1daemon-x-2
- RS&ORS
#輸入時以回車符為分隔符,空白行為換行符,localhost tmp]# cat data2Riley Mullen123 Main StreetChicago, IL 60601(312)555-1234Frank Williams456 Oak StreetIndianapolis, IN 46201(317)555-9876Haley Snell4231 Elm StreetDetroit, MI(313)555-4938localhost tmp]# awk 'BEGIN{FS="\n"; RS=""}{print $1 ,$4}' data2Riley Mullen (312)555-1234Frank Williams (317)555-9876Haley Snell (313)555-4938
- FIELDWIDTHS
#以特定列為分隔localhost tmp]# cat data11005.3247596.37115-2.349194.0005810.1298100.1localhost tmp]# awk 'BEGIN{FIELDWIDTHS="3 5 2 5"} {print $1,$2,$3,$4}' data1100 5.324 75 96.37115 -2.34 91 94.00058 10.12 98 100.1
- 自定義變量
- 在腳本中給變量復制
變量名可以是任意數目的字母、數字和下劃線,但不能以數字開頭
- 實例
localhost ~]#awk 'BEGIN{test="hello everyone";print test}'hello everyonelocalhost ~]# awk 'BEGIN{x=4;x=x*2+3;print x}'11
- 實例
- 在命令行上給變量復制
localhost tmp]# cat data4data11 data12 data13data21 data22 data23data31 data32 data33localhost tmp]# cat script1BEGIN{print "The starting value is",n}{print $n}localhost tmp]# awk -v n=3 -f script1 data4The starting value is 3data13data23data33
- 在腳本中給變量復制
- 內建變量:字段和記錄分隔符變量
- 數組變量
var[index] = elementvar:變量名index:索引值element:數據元素值
- 遍歷數組變量
for (var in array){ statements}
for語句在每次循環時將關聯數組array下一個索引值賦給變量var,然后執行一遍statements
- 實例
localhost ~]# awk 'BEGIN{var["a"] =1;var["b"]=2;var["c"]=3;var["d"]=4;for (i in var) {print var[i]}}' 1 2 3 4 #統計IP鏈接數 localhost ~]# awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log 192.168.1.48 10 #統計tcp鏈接狀態和數量,IPV4 localhost ~]# netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}' LISTEN 2 ESTABLISHED 3 #統計/etc/fstab文件中每個文件系統類型出現的次數 localhost ~]# awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab xfs 1 #統計指定文件中每個單詞出現的次數; localhost ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab
- 實例
- 遍歷數組變量
- 字符串匹配
// 純字符匹配 !// 純字符不匹配 ~// 字段值匹配 !~// 字段值不匹配 ~/a1|a2/ 字段值匹配a1或a2
- 實例
#顯示mysql相關信息 localhost ~]# awk '/mysql/{print $0}' /etc/passwd mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin #顯示非mysql localhost ~]# awk '!/mysql/{print $0}' /etc/passwd #顯示mail和mysql localhost ~]# awk '/mail|mysql/{print $0}' /etc/passwd mail:x:8:12:mail:/var/spool/mail:/sbin/nologin mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin #顯示$1匹配mail localhost ~]# awk -F: '$1~/mail/{print $1}' /etc/passwd mail
- 實例
- 操作符
- 算數操作符
x+y: 加 x-y:減 x*y:乘 x/y:除 x^y:次方 x%y:余數
- 賦值操作符
= : x=y +=: x+=5 (x=x+5) -=: x-=5 (x=x-5) /=: x/=5 (x=x/5) %=: x%=5 (x=x%5) ^=: x^=5 (x=x^5) ++: x++ (x=x+1) --: x-- (x=x-1)
- 比較操作符
> >= < <= != ==
- 模式匹配符
~:是否匹配 !~:是否不匹配
- 邏輯操作符:
&& || !
- 條件表達式
selector?if-true-expression:if-false-expression 實例: ~]# awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd root:Sysadmin or SysUser bin:Sysadmin or SysUser daemon:Sysadmin or SysUser adm:Sysadmin or SysUser lp:Sysadmin or SysUser sync:Sysadmin or SysUser
- 算數操作符
- 控制語句
- if語句
if(condition) {statments} if(condition) {statments} else {statements}
實例:
#簡單的if語句 ~]# awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd root centos test linux testuser #if-else語句 ~]# awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd ~]#awk -F: '{if($3>=1000) printf "Common user: %s\n",$1; else printf "root or Sysuser: %s\n",$1}' /etc/passwd root or Sysuser: root root or Sysuser: bin root or Sysuser: daemon root or Sysuser: adm root or Sysuser: lp #在if中執行多條語句和if-else語句 [root@localhost tmp]# cat data1 10 5 13 50 34 [root@localhost tmp]# awk '{if ($1>20) {x= $1*2; print $1,x}}' data1 50 100 34 68 ~]# awk '{if($1>20) print $1*2;else print $1/2}' data1 5 2.5 6.5 100 68 #打印磁盤使用率超過10%的 ~]# df -h | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>=10) print $1}' /dev/mapper/cl-root /dev/sda1
- while循環
while(conditon) {statments} 條件“真”,進入循環;條件“假”,退出循環
實例:對一行內的多個字段逐一類似處理時使用;對數組中的各元素逐一處理時使用
~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg linux16 7 /vmlinuz-3.10.0-514.el7.x86_64 30 root=/dev/mapper/cl-root 24 ro 2 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17 rhgb 4 quiet 5 LANG=en_US.UTF-8 16 linux16 7 /vmlinuz-0-rescue-071d709683fd4359a4845645d1906b29 50 root=/dev/mapper/cl-root 24 ro 2 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17 rhgb 4 quiet 5 ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)}; i++}}' /etc/grub2.cfg linux16 7 /vmlinuz-3.10.0-514.el7.x86_64 30 root=/dev/mapper/cl-root 24 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17 LANG=en_US.UTF-8 16 linux16 7 /vmlinuz-0-rescue-071d709683fd4359a4845645d1906b29 50 root=/dev/mapper/cl-root 24 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17
- do-while循環
至少執行一次循環體
- for循環
for(expr1;expr2;expr3) {statements}
實例
~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg linux16 7 /vmlinuz-3.10.0-514.el7.x86_64 30 root=/dev/mapper/cl-root 24 ro 2 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17 rhgb 4 quiet 5 LANG=en_US.UTF-8 16 linux16 7 /vmlinuz-0-rescue-071d709683fd4359a4845645d1906b29 50 root=/dev/mapper/cl-root 24 ro 2 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17 rhgb 4 quiet 5
- if語句
- 內建函數
- 數學函數
atan2(x, y) x/y的反正切,x和y以弧度為單位 cos(x) x的余弦,x以弧度為單位 exp(x) x的指數函數 int(x) x的整數部分,取靠近零一側的值 log(x) x的自然對數 rand( ) 比0大比1小的隨機浮點值 sin(x) x的正弦,x以弧度為單位 sqrt(x) x的平方根 srand(x) 為計算隨機數指定一個種子值
- 字符串函數
asort(s [,d]) 將數組s按數據元素值排序。索引值會被替換成表示新的排序順序的連續數字。另外,如果指定了d,則排序后的數組會存儲在數組d中 asorti(s [,d]) 將數組s按索引值排序。生成的數組會將索引值作為數據元素值,用連續數字索引來表明排序順序。另外如果指定了d,排序后的數組會存儲在數組d中 gensub(r, s, h [, t]) 查找變量$0或目標字符串t(如果提供了的話)來匹配正則表達式r。如果h是一個以g或G開頭的字符串,就用s替換掉匹配的文本。如果h是一個數字,它表示要替換掉第h處r匹配的地方 gsub(r, s [,t]) 查找變量$0或目標字符串t(如果提供了的話)來匹配正則表達式r。如果找到了,就全部替換成字符串s index(s, t) 返回字符串t在字符串s中的索引值,如果沒找到的話返回0 length([s]) 返回字符串s的長度;如果沒有指定的話,返回$0的長度 match(s, r [,a]) 返回字符串s中正則表達式r出現位置的索引。如果指定了數組a,它會存儲s中匹配正則表達式的那部分 split(s, a [,r]) 將s用FS字符或正則表達式r(如果指定了的話)分開放到數組a中。返回字段的總數 sprintf(format,variables) 用提供的format和variables返回一個類似于printf輸出的字符串 sub(r, s [,t]) 在變量$0或目標字符串t中查找正則表達式r的匹配。如果找到了,就用字符串s替換掉第一處匹配 substr(s, i [,n]) 返回s中從索引值i開始的n個字符組成的子字符串。如果未提供n,則返回s剩下的部分 tolower(s) 將s中的所有字符轉換成小寫 toupper(s) 將s中的所有字符轉換成大寫
- 時間函數
mktime(datespec) 將一個按YYYY MM DD HH MM SS [DST]格式指定的日期轉換成時間戳值① strftime(format[,timestamp])將當前時間的時間戳或timestamp(如果提供了的話)轉化格式化日期(采用shell函數date()的格式) systime( ) 返回當前時間的時間戳
- 數學函數
本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/101093