簡介
awk是一個強大的文本分析工具,相對於grep的查找,sed的編輯,awk在其對數據分析並生成報告時,顯得尤爲強大。簡單來說awk就是把文件逐行的讀入,以空格爲默認分隔符將每行切片,切開的部分再進行各種分析處理。
使用方法
awk ‘{pattern + action}’ {filenames}
其中 pattern 表示 AWK 在數據中查找的內容,而 action 是在找到匹配內容時所執行的一系列命令。花括號({})不需要在程序中始終出現,但它們用於根據特定的模式對一系列指令進行分組。
舉例子
- 顯示最近登錄的5個帳號
last -n 5 | awk '{print $1}'
- 顯示/etc/passwd的賬戶
cat /etc/passwd |awk -F ':' '{print $1}'
- 顯示/etc/passwd的賬戶和賬戶對應的shell,而賬戶與shell之間以逗號分割,而且在所有行添加列名name,shell,在最後一行添加”blue,/bin/nosh”。
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}'
awk工作流程是這樣的:先執行BEGING,然後讀取文件,讀入有/n換行符分割的一條記錄,然後將記錄按指定的域分隔符劃分域,填充域,
- 搜索/etc/passwd有root關鍵字的所有行,並顯示對應的shell
awk -F: '/root/{print $7}' /etc/passwd
這種是pattern的使用示例,匹配了pattern(這裏是root)的行纔會執行action(沒有指定action,默認輸出每行的內容)
awk內置變量
- 統計/etc/passwd:文件名,每行的行號,每行的列數,對應的完整行內容:
awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
awk編程
變量和賦值
下面統計/etc/passwd的賬戶人數
awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
count是自定義變量。之前的action{}裏都是隻有一個print,其實print只是一個語句,而action{}可以有多個語句,以;號隔開。
這裏沒有初始化count,雖然默認是0,但是妥當的做法還是初始化爲0:
awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd
統計某個文件夾下的文件佔用的字節數
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
注意,統計不包括文件夾的子目錄。
條件語句
統計某個文件夾下的文件佔用的字節數,過濾4096大小的文件(一般都是文件夾):
ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}'
數組
因爲awk中數組的下標可以是數字和字母,數組的下標通常被稱爲關鍵字(key)。值和關鍵字都存儲在內部的一張針對key/value應用hash的表格裏。一般而言,awk中的數組用來從記錄中收集信息,可以用於計算總和、統計單詞以及跟蹤模板被匹配的次數等等。
條件操作符
<、<=、==、!=、>=、~匹配正則表達式、!~不匹配正則表達式
- 如果第四個域包含ASIMA,就打印整條
awk '{if ($4~/ASIMA/) print $0}' temp
- 只打印第3域等於”48”的記錄
awk '$3=="3" {print $0}' temp
第一個域小於第2個域
awk '{if ($1<$2) print $1 "is smaller"}' temp
設置大小寫: awk ‘/[Gg]reen/’ temp
AND與關係: awk ‘{if ( 1=="a" && 2==”b” ) print $0}’ temp
awk ‘{if (
awk內置字符串函數
gsub(r,s) 在整個$0中用s替代r
awk 'gsub(/name/,"xingming") {print $0}' temp
index(s,t) 返回s中字符串t的第一位置
awk 'BEGIN {print index("Suny","ny")}' temp
多個文件合併操作。
與其他命令配合使用
如果work_dir下的某個模塊文件數大於20個則刪除
WORK_DIR=/usr/locol/testmod
find ${WORK_DIR}_bk -maxdepth 1 -type d | grep -v "${WORK_DIR}_bk$" | xargs ls -ldt | awk -v service_name=$SERVICENAME '{if(NR>20 && $9 ~/'$service_name'/){print $9}}' | xargs rm -rf
該命令爲找到當前目錄上一級目錄名稱爲testmod_bk
的文件夾。找到名稱 爲testmod_bk,按時間排序,如果記錄大於 20,名冊匹配則刪除
第6 或7或8列匹配相應的名稱則將相應的進程強制kill
ps ax | awk '($6 ~ "^'$BIN_DIR'") || ($7 ~ "^'$BIN_DIR'") || ($8 ~ "^'$BIN_DIR'") {print "kill -9 "$1;}' | /bin/sh 1>/dev/null 2>&1
將某個文件中的內容以固定的jason格式輸出
源文件格式爲
1 test.com abc.test.com
awk ’
BEGIN {FS=”\t”;}
FILENAME=="'$TMP_DIR'/test.list" {
printf "{";
printf "\"ID\":"$1", ";
printf "\"ZONE\":\""$2"\", ";
printf "\"DOMAIN\":"$3", ";
printf "\"CLASS\":\"IN\", ";
printf "\"TTL\":"600", ";
print "}";
}
' $TMP_DIR/test.list >$DATA_DIR/test.kxfr
輸出後的文件
{“ID”:”1”,”ZONE”:”test.com”,”DOMAIN”:”abc.test.com”“,CLASS”:”IN”,“TTL”:600}
總結
awk功能強大。在文本處理方面比較優秀。能解決很多實際問題。另外AWK能與其他linux命令很好的配合使用。需要不斷的練習纔會熟練的使用。