一、AWK傾向於一行一行的數據進行處理
主要三個參數:FS、NR、NF
1>FS:定義分隔符的,沒有的時候默認是空格符 格式:{FS=「:」}
也能夠多域分割
awk -F"[: +]" '{print $1,$2}' ceshi
awk -F":| |+" '{print $1,$2}' ceshi
上述兩種狀況是同樣的
2>NR:處理的是哪一行 好比:NR==1{printf 。。。。。。。} 第一行應該怎麼輸出
3>NF:每一行擁有的字段總數($0)數組
cat /etc/passwd | awk '{FS=":"} $3 < 10 {print $1 "\t " $3}' 定義分隔符和條件而後輸出(默認第一行仍是空格符)
cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}' 加上BEGIN能夠搞定
cat pay.txt | awk 'NR==1{printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total" }
NR>=2{total = $2 + $3 + $4
printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total}' *****AWK中定義變量在輸出時不須要加$ui
grep --color DELETE V2.txt |awk '{if ($2=="FROM") print $3; else print $4}'spa
AWK常與printf連用,因此對printf的語法也得熟悉
printf
%d 有符號十進制整數
%f 浮點數、十進制記數法
%s 字符串命令行
ls -ld /data/ww/edi/renbao |awk '{print $NF}' 直接打印出renbao 跟 $9同樣字符串
awk -F":" '{if ($3>500) print $1}' /etc/passwd 先判斷條件篩選在分割,集成了grep的功能input
當有這種狀況出現時得加擴展符號,好比
aaa-bbb:::cccc dddd
awk -F"[: ]+" '{print $2,$3}' 上述文件
打印出cccc dddd 就是直接以多個:或者多個空格爲分隔符it
awk -F":" '$3>500 {print $1}' /etc/passwd
awk -F":" '$1 ~ /^l/ {print $1}' /etc/passwd 匹配第一個域已c打頭的行,而後打印第一個域
awk -F":" '$1 !~ /^l/ {print $1}' /etc/passwd 不是以那個打頭的
awk -F":" BEGIN '{print "zhanghao,uid"} $3>500 {print $0}' /etc/passwd 先打印BEGIN的輸出,而後讀入內容$0 表明全部
awk -F":" 'BEGIN {print "zhanghao,gid"} $3 >500 {print $1,$3} END {print "ceshi,ceshi"}' /etc/passwd 先打印BEGIN,在讀完全部輸出,最後打印END的內容io
awk -F"分隔符" 'BEGIN {print "讀取文件以前的初始打印值"} 模式匹配動做 {print action/執行動做} END {print "執行完成以後最後的打印動做"}' +filename
自帶變量FILENAME 輸入文件名
$0 匹配行的全部輸出(按行讀取)
$NF 結尾的域
$ 分隔符對應的域test
自定義變量,統計目錄文件總字節
ls -l |awk 'BEGIN {size=0} {size+=$5} END {print size}'
BEGIN後面接的第一個是首次讀入的,餘下的是沒讀取一個都會讀入一次,END後面跟的是隻有在全部輸入完成以後纔讀入
ls -l |awk '{size=0} {size+=$5} END {print size}' 好比這個就是最後一個文件的大小,由於每次讀入的時候,size清0了awk
第一次BEGIN值0,無打印
第二次讀入0,打印0
第三次讀入8,打印8
第四次讀入210,打印218
第五次讀入1995,打印2213
最後結尾在打印一遍最終的值
awk '{print NR}' filename; //打印行號
awk ‘{print $0}' filename; //打印整行
awk '$0~/^$/ {print NR}' file //打印整行,而後作匹配,知足匹配的就打印出行號,
awk '$0="SET "NR" "$0' 1.txt //整行先替換成set,在打印行號,而後在輸出這行內容
awk 'NF{a++;print a,$0;next}1' 1.txt //首先匹配本行是否爲空,若是爲空執行默認的1打印空行,若是沒有的話就不輸出,非空就打印匹配規則
awk 'NR==FNR{a[FNR]=$1;b[FNR]=$2;next}NR>FNR{print a[FRN],b[FNR],$2,$3}' 2.txt 1.txt
###正向讀取,先讀取2.txt,a,b是隨意取的別名,讀取第一個文件,知足第一個條件,第一個和第二個賦值給a、b變量中的數據,當讀取第二個文件時,知足第二個條件(知足讀入總記錄大於當前文件記錄),跳過第一個動做,直接執行print(讀入第二個文件時確定是大於(NR>FNR),執行後面的模塊);若是第一個文件想要輸出多個,直接在第一個模塊加變量便可
一、當awk讀取的文件只有兩個的時候,比較經常使用的有兩種方法
一種是awk 'NR==FNR{...}NR>FNR{...}' file1 file2 或awk 'NR==FNR{...}NR!=FNR{...}' file1 file2
另外一種是 awk 'NR==FNR{...;next}{...}' file1 file2
瞭解了FNR和NR這兩個awk內置變量的意義就很容易知道這兩種方法是如何運做的
QUOTE:
FNR The input record number in the current input file. #已讀入當前文件的記錄數
NR The total number of input records seen so far. #已讀入的總記錄數
next Stop processing the current input record. The next input record is
read and processing starts over with the first pattern in the AWK
program. If the end of the input data is reached, the END block(s),
if any, are executed.
對於awk 'NR==FNR{...}NR>FNR{...}' file1 file2
讀入file1的時候,已讀入file1的記錄數FNR必定等於awk已讀入的總記錄數NR,由於file1是awk讀入的首個文件,故讀入file1時執行前一個命令塊{...}
讀入file2的時候,已讀入的總記錄數NR必定>讀入file2的記錄數FNR,故讀入file2時執行後一個命令塊{...}
對於awk 'NR==FNR{...;next}{...}' file1 file2
讀入file1時,知足NR==FNR,先執行前一個命令塊,但由於其中有next命令,故後一個命令塊{...}是不會執行的
讀入file2時,不知足NR==FNR,前一個命令塊{..}不會執行,只執行後一個命令塊{...}
二、當awk處理的文件超過兩個時,顯然上面那種方法就不適用了。由於讀第3個文件或以上時,也知足NR>FNR (NR!=FNR),顯然沒法區分開來。
因此就要用到更通用的方法了:
a、ARGIND 當前被處理參數標誌: awk 'ARGIND==1{...}ARGIND==2{...}ARGIND==3{...}... ' file1 file2 file3 ...
b、ARGV 命令行參數數組: awk 'FILENAME==ARGV[1]{...}FILENAME==ARGV[2]{...}FILENAME==ARGV[3]{...}...' file1 file2 file3 ...
c、把文件名直接加入判斷: awk 'FILENAME=="file1"{...}FILENAME=="file2"{...}FILENAME=="file3"{...}...' file1 file2 file3 ... #沒有前兩種通用
awk 'ARGIND==1{A=$0;next}ARGIND==2{B=$2;c=$3;d=$4;next}ARGIND==3{print A,B,c,d,$2,$3,$4}' 1.txt 2.txt 3.txt
###等於1,先讀第一個,整行賦值,等於2讀取第二個,對應的分段域複製給不一樣的變量,讀取第三個直接打印,把前面存儲的變量以及最後讀取的文件須要的域直接打印便可
ovs-vsctl show |awk 'NR==1{B=$0}NF{a=$0}END{print a,B}'
awk if循環運用
awk -F":" 'BEGIN{count=0;print "[start] privileges count is",count}{if($3==0){print $0}else if($3>1000){print $1,"test user";count+=2*$3} else {print $1,$3;count+=$3}}END{print "[end] privileges count is",count}' /etc/passwd
awk 數組引用,按照順序讀取
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
匹配$1出現的次數,key就是$1,value就是出現的次數,這種方式是無序的
awk '{array[$1]++}{for (i in array) print i,array[i]}' file
FILENAME:文件名;NR:第多少行;NF:最後一列是第多少列,加上$就是最後一列的輸出
awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
awk也支持常規的正常匹配,經過正則匹配來帥選須要的行在進行action