一.基本介紹
1.awk:
awk是一個(gè)強(qiáng)大的文本分析工具,在對(duì)文本文件的處理以及生成報(bào)表,awk是無可替代的。awk認(rèn)為文本文件都是結(jié)構(gòu)化的,它將每一個(gè)輸入行定義為一個(gè)記錄,行中的每個(gè)字符串定義為一個(gè)域(段),域和域之間使用分割符分割。
2.功能:流控制、數(shù)學(xué)運(yùn)算、進(jìn)程控制、內(nèi)置的變量和函數(shù)、循環(huán)和判斷
3.工作原理:
awk 會(huì)把每行進(jìn)行一個(gè)拆分,用相應(yīng)的命令對(duì)拆分出來的“段”進(jìn)行處理。
(1)行工作模式,讀入文件的每一行,會(huì)把一行的內(nèi)容,存到$0里
(2)使用內(nèi)置的變量FS(段的分隔符,默認(rèn)用的是空白字符),分割這一行,把分割出來的每個(gè)段存到相應(yīng)的變量$(1-100)
(3)輸出的時(shí)候按照內(nèi)置變量OFS(out FS),輸出
(4)讀入下一行繼續(xù)操作
簡單實(shí)例
[root@tx3 ~]# echo "this is a book" > awk.txt
[root@tx3 ~]# awk '{print $2,$1,$3,$4}' awk.txt
is this a book
4. ? Awk常用內(nèi)置變量表:
1 $0 ? ? ? ? ? ? 當(dāng)前記錄(作為單個(gè)變量)
2 $1~$n ? ? ? ? ?當(dāng)前記錄的第n個(gè)字段,字段間由FS分隔
3 FS ? ? ? ? ? ? 輸入字段分隔符 默認(rèn)是空格
4 NF ? ? ? ? ? ? 當(dāng)前記錄中的字段個(gè)數(shù),就是有多少列
5 NR ? ? ? ? ? ? 已經(jīng)讀出的記錄數(shù),就是行號(hào),從1開始
6 RS ? ? ? ? ? ? 輸入的記錄他隔符默 認(rèn)為換行符
7 OFS ? ? ? ? ? ?輸出字段分隔符 默認(rèn)也是空格
8 ORS ? ? ? ? ? ?輸出的記錄分隔符,默認(rèn)為換行符
9 ARGC ? ? ? ? ? 命令行參數(shù)個(gè)數(shù)
10 ARGV ? ? ? ? ? 命令行參數(shù)數(shù)組
11 FILENAME ? ? ? 當(dāng)前輸入文件的名字
12 IGNORECASE ? ? 如果為真,則進(jìn)行忽略大小寫的匹配
13 ARGIND ? ? ? ? 當(dāng)前被處理文件的ARGV標(biāo)志符
14 CONVFMT ? ? ? ?數(shù)字轉(zhuǎn)換格式 %.6g
15 ENVIRON ? ? ? ?UNIX環(huán)境變量
16 ERRNO ? ? ? ? ?UNIX系統(tǒng)錯(cuò)誤消息
17 FIELDWIDTHS ? ?輸入字段寬度的空白分隔字符串
18 FNR ? ? ? ? ? ?當(dāng)前記錄數(shù)
19 OFMT ? ? ? ? ? 數(shù)字的輸出格式 %.6g
20 RSTART ? ? ? ? 被匹配函數(shù)匹配的字符串首
21 RLENGTH ? ? ? ?被匹配函數(shù)匹配的字符串長度
二.print的簡單使用
例:打印整行: $0
[root@tx3 ~]# cp /etc/passwd p1
[root@tx3 ~]# awk '{print $0}' p1
例:打印每行的最后一個(gè)字段: $NF
[root@tx3 ~]# awk -F : '{print $NF}' p1
例:打印第三個(gè)字段: $3
[root@tx3 ~]# awk -F : '{print $3}' p1
例:打印第一行NR==1
[root@tx3 ~]# awk 'NR==1{print $0}' p1
root:x:0:0:root:/root:/bin/bash
例:打印最后一行
[root@tx3 ~]# awk 'END{print $0}' p1
tx:x:500:500:tx:/home/tx:/bin/bash
例:打印第一行最后一個(gè)字段
[root@tx3 ~]# awk -F: 'NR==1{print $NF}' p1
/bin/bash
例:打印最后一行最后一個(gè)字段
[root@tx3 ~]#awk -F: 'END{print $NF}' p1
例:打印每行的倒數(shù)第二個(gè)字段,并在其后打印你好
[root@tx3 ~]# awk -F: '{print $(NF-1),"nihao"}' p1
/root nihao
/bin nihao
/sbin nihao
例:打印行號(hào)
[root@tx3 ~]# awk '{print NR,$0}' p1
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
例:打印當(dāng)前系統(tǒng)環(huán)境變量的某個(gè)特定值
[root@tx3 ~]# awk 'BEGIN{print ENVIRON["PATH"];}'
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
例: 用:分割,刪除第2個(gè)字段
[root@tx3 ~]# awk 'BEGIN{FS=":";OFS=":"}{print $1,$3,$4,$5,$6,$7}' p1
root:0:0:root:/root:/bin/bash
bin:1:1:bin:/bin:/sbin/nologin
daemon:2:2:daemon:/sbin:/sbin/nologin
三.printf的使用
print format 生成報(bào)表
%d ? ? ? ?十進(jìn)制有符號(hào)整數(shù)
%u ? ? ? ?十進(jìn)制無符號(hào)整數(shù)
%f ? ? ? ?浮點(diǎn)數(shù)
%s ? ? ? ?字符串
%c ? ? ? ?顯示字符的ASCII碼
%p ? ? ? ?指針的值
%e ? ? ? ?科學(xué)技術(shù)法顯示數(shù)值
%x ? ? ? ?%X 無符號(hào)以十六進(jìn)制表示的整數(shù)
%o ? ? ? ?無符號(hào)以八進(jìn)制表示的整數(shù)
%g ? ? ? ?%G 以科學(xué)計(jì)數(shù)法或浮點(diǎn)數(shù)的格式顯示數(shù)值
%% ? ? ? ?顯示其自身
修飾符:
-: ?左對(duì)齊
+: ?顯示數(shù)值符號(hào)
N: 顯示
-F 指定段的分隔符
例:(1)生成報(bào)表
例:(2)小數(shù)問題
對(duì)小數(shù)取保留位的時(shí)候,四舍五入
對(duì)小數(shù)取整,不進(jìn)行四舍五入
[root@tx3 ~]# cat awk.1
23.3456 11.234 45.67
[root@tx3 ~]# awk '{printf "%.2f\t%.2f\t%.2f\n",$1,$2,$3}' awk.1
23.3511.2345.67
四.a(chǎn)wk的使用
(1)正則表達(dá)式
\(\) ? \{\} 不支持
. * ^ $ ? + [] | \< \> () ?可以直接使用
例[root@tx3 ~]# awk '/^$/{print "this is an empty line"}' /etc/inittab
this is an empty line
this is an empty line
this is an empty line
this is an empty line
this is an empty line
this is an empty line
this is an empty line
this is an empty line
this is an empty line
例[root@tx3 ~]# awk -F: '/^root/{print $1,$NF}' /etc/passwd
root /bin/bash
例[root@tx3 ~]# awk -F: '!/^root/{print $1,$NF}' /etc/passwd|head -3
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
(2)關(guān)系運(yùn)算符
> < == != >= <=
~(匹配) !~(不匹配)
例[root@tx3 ~]# cp /etc/passwd p1
[root@tx3 ~]# awk -F: '$3 == 0 {print $1}' p1
Root
例[root@tx3 ~]# awk -F: '$3 != 0{ print $1}' p1 | head -2
bin
Daemon
例[root@tx3 ~]# awk -F: '$3 < 2 {print $1}' p1
root
bin
(3)邏輯運(yùn)算符
&& || !
與 或 非
例[root@tx3 ~]# awk -F: '$3 > 0 && $3 < 10 {print $1, $3}' p1 |head -2
bin 1
daemon 2
例[root@tx3 ~]# ?awk -F: '$3 > 10 || $3 < 5 {print $1,$3}' p1 |head -6
root 0
bin 1
daemon 2
adm 3
lp 4
operator 11
(4)算數(shù)運(yùn)算符
+ - * / %(取模(余數(shù))) ^(冪運(yùn)算)
例:輸出名字,總成績,平均成績
[root@tx3 ~]# cat cj
tx 90 86 86
tx1 89 78 85
tx2 79 80 85
[root@tx3 ~]# ?awk '{print $1,$2+$3+$4,($2+$3+$4)/3}' cj
tx 262 87.3333
tx1 252 84
tx2 244 81.3333
[root@tx3 ~]# awk '{printf"%-5s %3d %.2f\n",$1,$2+$3+$4,($2+$3+$4)/3}' cj
tx ? ?262 87.33
tx1 ? 252 84.00
tx2 ? 244 81.33
(5)BEGIN ?END
BEGIN{ 動(dòng)作;動(dòng)作;... } ?在處理文件之前,要執(zhí)行的動(dòng)作;只執(zhí)行一次
END{ 動(dòng)作;動(dòng)作;... } ? ?在處理完文件之后,要執(zhí)行的動(dòng)作;只執(zhí)行一次
BEGIN :可以給文件添加標(biāo)題、定義變量、定義文件的分隔符
END:匯總的操作
getline可以從管道和標(biāo)準(zhǔn)輸入讀取輸入,然后傳遞給變量。
例:
[root@tx3 ~]# awk 'BEGIN{"date"| getline a}{print}END{print a}' cj
tx 90 86 86
tx1 89 78 85
tx2 79 80 85
Thu Feb ?7 12:39:25 CST 2013
五.a(chǎn)wk里的流控制和循環(huán)
(1)簡單的條件判斷
語法:(表達(dá)式 ? 值1 : 值2) 如果表達(dá)式成立,輸出值1;否則輸出值2
[root@tx3 ~]# cat num
2 8 9
8 4 6
3 5 7
[root@tx3 ~]# awk '{print ( $1 > $2 ? $1 : $2)}' num
8
8
5
(2)if判斷
語法:
{ if (表達(dá)式
{
動(dòng)作1;動(dòng)作2;...
}
}
如果表達(dá)式成立,那么執(zhí)行動(dòng)作。
[root@tx3 ~]# awk '{if ($2>=80 && $2 <=100) {print $1,"great"} else {print $1, "good"}}' cj
tx great
tx1 great
tx2 good
(2)多支判斷
{
if (表達(dá)式)
{ 動(dòng)作1;動(dòng)作2;...}
else if (表達(dá)式)
{ 動(dòng)作1;動(dòng)作2;...}
else if (表達(dá)式)
{ 動(dòng)作1;動(dòng)作2;...}
......
else
{ 動(dòng)作1;動(dòng)作2;...}
}
[root@tx3 ~]# cat cj
tx 90 86 86
tx1 89 78 85
tx2 79 80 85
tx3 80 70 60
tx4 75 85 65
tx5 78 62 80
判斷的標(biāo)準(zhǔn):
90-100 A
80-89 ?B
70-79 ?C
60-69 ?D
0-59 ? E
[root@tx3 ~]# awk '{ if ($2 >= 90 && $2 <= 100) {print $1,"A"} else if ($2 >= 80 && $2 < 90) {print $1,"B"} else if ($2 >= 70 && $2 < 80) {print $1,"C"} else if ($2 >= 60 && $2 < 70) {print $1,"D"} else {print $1,"E"} }' cj
tx A
tx1 B
tx2 C
tx3 B
tx4 C
tx5 C
(3)循環(huán)while
語法:'var=初值;while (表達(dá)式){動(dòng)作1;...更新變量的動(dòng)作;}'
例:
[root@tx3 ~]# awk -F: '{i=1; while (i<=NF) {print $i;i++}}' p1 | head -7
root
x
0
0
root
/root
/bin/bash
例. 方法一
[root@tx3 ~]# awk -F: '{i=NF; while (i>=2) {printf $i ":";i--};print $1}' p1
/bin/bash:/root:root:0:0:x:root
/sbin/nologin:/bin:bin:1:1:x:bin
/sbin/nologin:/sbin:daemon:2:2:x:daemon
/sbin/nologin:/var/adm:adm:4:3:x:adm
例. 方法二
[root@tx3 ~]# awk 'BEGIN { FS=":" } { i=NF; while (i>=2) {printf $i ":";i--} print $1}' p1
/bin/bash:/root:root:0:0:x:root
/sbin/nologin:/bin:bin:1:1:x:bin
/sbin/nologin:/sbin:daemon:2:2:x:daemon
(4)for循環(huán)
語法:
{
for(表達(dá)式)
{動(dòng)作1;...}
}
表達(dá)式:分為3部分:
(1)初始化表達(dá)式 i=1
(2)測試表達(dá)式 ? i<10
(3)更新測試表達(dá)式 i++
語句:
next 處理輸入行的下一個(gè)輸入行
exit 退出
continue 結(jié)束本次循環(huán)
break 跳出循環(huán)
例
[root@tx3 ~]# awk 'BEGIN {FS=":"} {for(i=NF;i>=2;i--) {printf $i ";"};print $1}' p1
/bin/bash;/root;root;0;0;x;root
/sbin/nologin;/bin;bin;1;1;x;bin
/sbin/nologin;/sbin;daemon;2;2;x;daemon
/sbin/nologin;/var/adm;adm;4;3;x;adm
例
[root@tx3 ~]# cat num
2 8 9
8 4 6
3 5 7
[root@tx3 ~]# awk '{ max=0; i=1; while (i<=NF) { if (max<$i) {max=$i} i++} print max}' num
9
8
7
(5)awk數(shù)組
例
例 ? 使用變量作為數(shù)組下標(biāo)
另外一種讀取方式(這種是無序的,j是變量,a是數(shù)組)
數(shù)組有序
(6)函數(shù)
@1split 切割字符串
split("等待被切割的字符串",數(shù)組名,"切割用的分隔符")
[root@tx3 ~]# awk 'BEGIN{split("2012/08/23",da,"/");print da[2],da[3],da[1]}'
08 23 2012
@2toupper() 小寫轉(zhuǎn)大寫
tolower() 大寫轉(zhuǎn)小寫
[root@tx3 ~]# awk '{print toupper($0)}' p1 |head -3
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH
BIN:X:1:1:BIN:/BIN:/SBIN/NOLOGIN
DAEMON:X:2:2:DAEMON:/SBIN:/SBIN/NOLOGIN
@3sub() ?局部替換
gsub() 全局替換
sub(/要替換的內(nèi)容/,"替換成什么內(nèi)容")
gsub(/要替換的內(nèi)容/,"替換成什么內(nèi)容")
gsub(/要替換的內(nèi)容/,"替換成什么內(nèi)容",指定字段如$7)
例:
[root@tx3 ~]# awk -F: '{sub(/root/,"r00t");print}' p1
r00t:x:0:0:root:/root:/bin/bash
例:
[root@tx3 ~]# awk -F: '{gsub(/root/,"r00t");print}' p1
r00t:x:0:0:r00t:/r00t:/bin/bash
operator:x:11:0:operator:/r00t:/sbin/nologin
例:
[root@tx3 ~]# awk -F[:/] '{gsub(/root/,"r00t",$7);print}' p1
root x 0 0 root ?r00t ?bin bash
operator x 11 0 operator ?r00t ?sbin nologin
@4.length() 計(jì)算字符串的長度
[root@tx3 ~]# awk -F: '{print length($1),$1}' p1
4 root
3 bin
6 daemon
3 adm
@5. 數(shù)學(xué)計(jì)算
[root@tx3 ~]# awk 'BEGIN{print sin(30)}'
-0.988032
[root@tx3 ~]# awk 'BEGIN{print cos(60)}'
-0.952413
[root@tx3 ~]# awk 'BEGIN{print int(22/6)}'
3
[root@tx3 ~]# awk 'BEGIN{print sqrt(3)}'
1.73205