awk命令簡介

簡介

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換行符分割的一條記錄,然後將記錄按指定的域分隔符劃分域,填充域,0, 1表示第一個域,$n表示第n個域,隨後開始執行模式所對應的動作action。接着開始讀入第二條記錄······直到所有的記錄都讀完,最後執行END操作。

  • 搜索/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 (1=="a"|| 1==”b”) print $0}’ temp

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命令很好的配合使用。需要不斷的練習纔會熟練的使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章