awk技巧,倒車入庫技巧圖解
awk預設就是空格和TAB,如果要指定用TAB可以用awk -F '\t'如果要指定多個TAB當作一個處理,可以用awk -F '\t+' ***********************1.基本完整用法***********************---1.基本完整用法last -n 5 |awk '!/^$/' | awk 'BEGIN {print "username,IP" } {print $1,$3} \END {print "最後登入的使用者和ip地址"}'---2.查看最後登入的五個使用者和ip地址並去掉空行last -n 5 |awk '!/^$/' | awk 'BEGIN {print "username,IP" } {print $1,$3} \END {print "最後登入的使用者和ip地址"}'--首選last -n 5 |awk 'BEGIN {print "username,IP" } !/^$/ {print $1,$3} \END {print "最後登入的使用者和ip地址"}'***********************----2.AWK迴圈***********************---2.1 顯示所有使用者名稱awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; \END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd---2.2迴圈顯示目錄名find /etc/sysconfig/network-scripts/ -name "ifcfg-*" |awk -F "/" ' {print $5}' >test.txtcat test.txtifcfg-em1ifcfg-em2ifcfg-loifcfg-em1ifcfg-em2ifcfg-loifcfg-em1ifcfg-em2ifcfg-loifcfg-08ifcfg-10ifcfg-l1--#帶行號顯示(數組)awk 'BEGIN {count=0;} {name[count] = $1;count++;}; \END{for (i = 0; i < NR; i++) print i, name[i]}' /root/test.txt---結果為:0 ifcfg-em11 ifcfg-em22 ifcfg-lo3 ifcfg-em14 ifcfg-em25 ifcfg-lo6 ifcfg-em17 ifcfg-em28 ifcfg-lo9 ifcfg-0810 ifcfg-1011 ifcfg-l1--#不帶行號顯示# awk '{for(i=1;i<=NF;i++) {printf $i" "} printf "\n"}' /root/test.txtifcfg-em1 ifcfg-em2 ifcfg-lo ifcfg-em1 ifcfg-em2 ifcfg-lo ifcfg-em1 ifcfg-em2 ifcfg-lo ifcfg-08 ifcfg-10 ifcfg-l1 df -H |awk -F '\t' '{ print $1,$2,$3,$4,$5,$6}'***********************3.awk模糊***********************--3.1模糊比對: 查詢第四列中是否含有Brown $awk '{if($4~/Brown/) print $0}' grade.txt 如果在文本中查詢字串"Brown",使用/Brown/ 和 $awk '$4~/Brown/' grade.txt 作用相同。--3.2模糊不匹配 $ awk '$0 !~ /Brown/' grade.txt $ awk '{if($4 !~ /Brown/) print $0' grade.txt--3.3匹配字元或字串# awk -F: '$1~/me/' passwd games:x:12:100:games:/usr/games:/sbin/nologin# awk -F: '$1~/user/' passwd user1:x:600:501::/home/user1:/bin/bash可以讓某個段去匹配,~ 表示匹配的意思,以冒號分隔第一欄位然後匹配//裡的關鍵字;123456# awk -F: '/root/ {print $1,$3} /user/ {print $1,$3}' passwd root 0operator 11ftp 14saslauth 499user1 600awk還可以多次匹配***********************4.精確匹配***********************$ awk '$3 == "48" {print $0}' grade.txt$ awk '{if ($3=="48") print $0}' grade.txt# awk -F: '$3=="0"' passwd root:x:0:0:root:/root:/bin/bash# awk -F: '$3==10' passwd uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin判斷第3個欄位為10的並且列印該行的第7欄位;1234# awk -F: '$3==10 {print $7}' passwd /sbin/nologin# awk -F: '$3=="600"' passwd user1:x:600:501::/home/user1:/bin/bashawk中是可以用邏輯符號判斷的,比如 ‘==’ 就是等於,也可以理解為 ‘精確匹配’ 另外也有 >, ‘>=, ‘<, ‘<=, ‘!= 等等,值得注意的是,在和數字比較時,若把比較的數字用雙引號引起來後,那麼awk不會認為是數字,而認為是字元,不加雙引號則認為是數字。樣本,雙引號括起來認為是字元;加單引號和不加則認為是數字;# awk -F: '$3>"500"' passwd | sort -t: -k 3 -n shutdown:x:6:0:shutdown:/sbin:/sbin/shutdownhalt:x:7:0:halt:/sbin:/sbin/haltmail:x:8:12:mail:/var/spool/mail:/sbin/nologinvcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologinsshd:x:74:74:privilege-separated ssh:/var/empty/sshd:/sbin/nologindbus:x:81:81:system message bus:/:/sbin/nologinpostfix:x:89:89::/var/spool/postfix:/sbin/nologinnobody:x:99:99:nobody:/:/sbin/nologinuser1:x:600:501::/home/user1:/bin/bash# awk -F: '$3>500' passwd | sort -t: -k 3 -n user1:x:600:501::/home/user1:/bin/bash# awk -F: '$3>'500'' passwd | sort -t: -k 3 -n user1:x:600:501::/home/user1:/bin/bash***********************5.精確不匹配***********************$awk '$4!="brwon" {print $0}' grade.txt# awk -F: '$7!="/sbin/nologin"' passwd root:x:0:0:root:/root:/bin/bashsync:x:5:0:sync:/sbin:/bin/syncshutdown:x:6:0:shutdown:/sbin:/sbin/shutdownhalt:x:7:0:halt:/sbin:/sbin/haltuser1:x:600:501::/home/user1:/bin/bashmysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash# awk -F: '$3>"5" && $3<"7"' passwd shutdown:x:6:0:shutdown:/sbin:/sbin/shutdownvcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologinuser1:x:600:501::/home/user1:/bin/bash另外還可以使用 && “並且”和 || “或者” 的意思。樣本,列印第3段大於第4段,並且第7段為/bin/bash的行;# awk -F: '$3>$4 && $7=="/bin/bash"' passwd user1:x:600:501::/home/user1:/bin/bashNOTE:尖角符號代表行首,“.”代表任一字元。***********************6.統計功能***********************netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'NOTE: ^ 是開頭的意思,就是說開頭是TCP字樣的,$NF表示最後一個欄位,把它放入數組S中,然後自加.END最後用for取出數組中的下標,也就是TCP的幾種狀態,然後對應該下標的值,就是統計的數量.理解如下:觀察一、先輸出兩個值,其中NF為awk正在處理記錄(行)的欄位總數,$NF為每行最後一個欄位的值# netstat -na |awk '/^tcp/ {print NF,$NF}'6 LISTEN6 LISTEN6 LISTEN6 LISTEN6 LISTEN6 LISTEN6 LISTEN6 LISTEN6 LISTEN6 LISTEN6 TIME_WAIT6 TIME_WAIT6 TIME_WAIT6 TIME_WAIT6 ESTABLISHED6 ESTABLISHED6 ESTABLISHED6 ESTABLISHED6 ESTABLISHED6 TIME_WAIT6 TIME_WAIT6 LISTEN6 LISTEN6 ESTABLISHED觀察二、如下命令輸出4個值,注意前後倆欄位的值是怎麼來的。。。S[LISTEN], ++S[LISTEN]# netstat -na |awk '/^tcp/ {print NF,$NF,S[$NF],++S[$NF]}'6 LISTEN 16 LISTEN 1 26 LISTEN 2 36 LISTEN 3 46 LISTEN 4 56 LISTEN 5 66 LISTEN 6 76 LISTEN 7 86 LISTEN 8 96 LISTEN 9 106 TIME_WAIT 16 ESTABLISHED 16 TIME_WAIT 1 26 TIME_WAIT 2 36 TIME_WAIT 3 46 ESTABLISHED 1 26 ESTABLISHED 2 36 ESTABLISHED 3 46 ESTABLISHED 4 56 LISTEN 10 116 LISTEN 11 126 ESTABLISHED 5 6觀察三、利用awk的行處理特性,遍曆了所有tcp開頭的行。定義出不同狀態命名的數組下標,並分別++計數賦值給數組元素,最後列印$NF和數組S[$NF]的值。觀察粗體部分 # netstat -na | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' TIME_WAIT 4ESTABLISHED 6LISTEN 12SYN_RECV表示正在等待處理的請求數;ESTABLISHED表示正常資料轉送狀態;TIME_WAIT表示處理完畢,等待逾時結束的請求數。***********************7.awk小技巧***********************第一行: NR==1 或 !i++第n行: NR==n最後一行: 0 或 "" 或 1==0 或 1>2 ,總之任一個假值就可以匹配RegexRE的行: /RE/--7.1取指定行--7.2從第二行開始列印awk 'FNR>1 { print $1}' a.txtawk 'NR==2,NR==0 { print $1}' a.txt--7.3取中間幾行awk '{if(NR>=302&&NR<=379)$0="#"$0}1' sphinx.conf--7.4列印每行,並刪除第二列awk '{$2="";print }' test.txt --7.5列印部分文本,即輸出所有行,但是第一、二列為空白awk '{ $1 = "";$3 = ""; print }' test1 --7.6列印檔案中除第一列和第三列外的其它列、同時從第二行開始列印awk 'BEGIN{print "ocpyang"} FNR>1 { $1 = "";$3 = ""; print }' test.txt --7.7列印檔案中除第一列和第三列外的其它列以及第一行第二行awk ' NR==1,NR==2 { $1 = "";$3 = ""; print }' test.txt --7.8文本間隔:# 每行後面增加一行空行awk '1;{print ""}'awk 'BEGIN{ORS="\n\n"};1'# 每行後面增加兩行空行awk '1;{print "\n"}'--7.9每句行前加上編號awk '{print FNR "\t" $0}' test.txt其中,0為顯示所有列;亦可用1,2來顯示1,2列--7.10用定位字元 (\t) 給所有檔案加上連貫的編號awk '{print NR "\t" $0}' test.txt ---7.11去除#開始的行同時刪除空行awk '!/^#/ && !/^$/ ' wsrep.cnf