greo:文本過濾器
sed:流編輯器
awk:報告生成器
gawk
#awk [options] 'script' file1 file2, ...
#awk [options] 'PATTERN {action}' file1 file2, ...
[root@localhost ~]# vi test.txt
this is a test.
[root@localhost ~]# awk '{print $0}' test.txt
this is a test.
[root@localhost ~]# awk '{print $1}' test.txt
this
[root@localhost ~]# awk '{print $2}' test.txt
is
[root@localhost ~]# awk '{print $3}' test.txt
a
[root@localhost ~]# awk '{print $4}' test.txt
test.
[root@localhost ~]# awk '{print $1,$3}' test.txt
this a
#BEGIN{OFS=" "}指定輸出分隔符
[root@localhost ~]# awk 'BEGIN{OFS="#"} {print $2,$1,$3}' test.txt
is#this#a
[root@localhost ~]# awk 'BEGIN{OFS=":"}{print "hello",$1,$2,$3,$4}' test.txt
hello:this:is:a:test.
awk -F: 指定已有的分隔符爲: ,即輸出分隔符
OFS自定義分隔符顯示。即輸入分隔符
FS=":"讀取文本時所使用的字段分隔符
RS 輸入文本信息所使用的換行符
NR 相對於所有文件awk命令所處理的第多少行。
FNR 相對於當前文件awk命令所處理的第多少行。
NF 顯示字段總數
[root@localhost ~]# awk '{print NF}' test.txt
4
[root@localhost ~]# awk '{print $NF}' test.txt 顯示最後一個字段
test.
在命令行中定義變量 -v
[root@localhost ~]# awk -v test="hello awk" 'BEGIN{print test}'
hello awk
[root@localhost ~]# awk 'BEGIN{test="hello awk";print test}'
hello awk
format 格式的提示符都以%開頭,後跟一個字符:如下:
%c 顯示字符的ASCII碼
[root@localhost ~]# awk '{printf "%c\n",$1}' test.txt
t
%d,%i 十進制整數
%e,%E科學計數法的格式或浮點數的格式顯示數值;
%f 顯示浮點數
%g,%G科學計數法的格式或浮點數的格式顯示數值;
%s 顯示字符串
[root@localhost ~]# awk '{printf "%s\n",$1}' test.txt
this
%u 無符號整數
%% 顯示%自身
修飾符:
N:顯示寬度
[root@localhost ~]# awk '{printf "%10s\n",$1}' test.txt
this
-:左對齊
[root@localhost ~]# awk '{printf "%-10s\n",$1}' test.txt
this
[root@localhost ~]# awk '{printf "%-10s%-10s\n",$1,$3}' test.txt
this a
+:顯示數值符號
以十進制數字查看用戶ID號:
[root@localhost ~]# awk -F: '{printf "%5d\n",$3}' /etc/passwd
0
1
2
3
4
5
6
7
8
10
11
12
13
14
99
81
69
32
173
29
65534
68
38
499
89
74
72
16
以科學計數法顯示
[root@localhost ~]# awk -F: '{printf "%5e\n",$3}' /etc/passwd
0.000000e+00
1.000000e+00
2.000000e+00
3.000000e+00
4.000000e+00
5.000000e+00
6.000000e+00
7.000000e+00
8.000000e+00
1.000000e+01
1.100000e+01
1.200000e+01
1.300000e+01
1.400000e+01
9.900000e+01
8.100000e+01
6.900000e+01
3.200000e+01
1.730000e+02
2.900000e+01
6.553400e+04
6.800000e+01
3.800000e+01
4.990000e+02
8.900000e+01
7.400000e+01
7.200000e+01
1.600000e+01
awk的操作符
-x:負值
+x:轉換爲數值
x**y 次方
x*y 乘法
x/y除法
x+y
x-y
x%y
比較操作符
x < y
x <= y
x > y
x >= y
x == y
x != y
x ~ y x的字符串能夠被y這個模式匹配到則爲真否則爲假
x !~ y
subscript in array True if the array array has an element with the
subscript subscript. 表示subscript中有沒有array這個元素 有則爲真,沒有則爲假
表達式間的邏輯關係
&&
||
條件表達式
selector?if-true-exp:if-false-exp
if selector;then
if-true-exp
else
if-false-exp
fi
常用的模式類型
Regexp:正則表達式,格式爲/regular expression
expression:表達式,其值非0或爲非空字符時滿足條件 如:$1 ~ /foo/或$1 == "my",運
算符~(匹配)和!~(不匹配)
Ranges:指定的匹配範圍,格式pat1,pat2
BEGIN/END:特殊模式,僅在awk命令執行前運行一次或結束前運行一次
Empty (空模式):匹配任意輸入行
常見的Action
Expression
Control statements
Compound statements
Input statements
Output statements
顯示r開頭的行
[root@localhost ~]# awk '/^r/{print $1}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
rpc:x:32:32:Rpcbind
rpcuser:x:29:29:RPC
顯示從第一以root開頭的行到第一個以m開頭的行的第1和第7個字段並以:爲分隔符
[root@localhost ~]# awk -F: '$3==0,/^m/{print $1,$7}' /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
顯示從第一以root開頭的行到第一次$7匹配到nologin的行的第1,2,7個字段並以:爲分隔
符
[root@localhost ~]# awk -F: '$3==0,$7~"nologin"{print $1,$2,$7}' /etc/passwd
root x /bin/bash
bin x /sbin/nologin
[root@localhost ~]# awk -F: '$3==0,$7~"nologin"{printf "%-10s%-10s%-20s\n",
$1,$2,$7}' /etc/passwd
root x /bin/bash
bin x /sbin/nologin
[root@localhost etc]# awk -F: 'BEGIN{printf "Username ID shell\n"} {printf "%-10s%-10s%-20s\n",$1,$2,$7}' /etc/passwd
Username ID shell
root x /bin/bash
bin x /sbin/nologin
daemon x /sbin/nologin
adm x /sbin/nologin
lp x /sbin/nologin
sync x /bin/sync
shutdown x /sbin/shutdown
halt x /sbin/halt
mail x /sbin/nologin
uucp x /sbin/nologin
operator x /sbin/nologin
games x /sbin/nologin
gopher x /sbin/nologin
ftp x /sbin/nologin
nobody x /sbin/nologin
dbus x /sbin/nologin
vcsa x /sbin/nologin
rpc x /sbin/nologin
abrt x /sbin/nologin
rpcuser x /sbin/nologin
nfsnobody x /sbin/nologin
haldaemon x /sbin/nologin
ntp x /sbin/nologin
saslauth x /sbin/nologin
postfix x /sbin/nologin
sshd x /sbin/nologin
tcpdump x /sbin/nologin
oprofile x /sbin/nologin
mysql x /sbin/nologin
END只在最後打印一次
[root@localhost etc]# awk -F: 'BEGIN{printf "Username ID shell\n"} {printf "%-10s%-10s%-20s\n",$1,$2,$7}END{print "End of report"}' /etc/passwd
root x /bin/bash
bin x /sbin/nologin
daemon x /sbin/nologin
adm x /sbin/nologin
lp x /sbin/nologin
sync x /bin/sync
shutdown x /sbin/shutdown
halt x /sbin/halt
mail x /sbin/nologin
uucp x /sbin/nologin
operator x /sbin/nologin
games x /sbin/nologin
gopher x /sbin/nologin
ftp x /sbin/nologin
nobody x /sbin/nologin
dbus x /sbin/nologin
vcsa x /sbin/nologin
rpc x /sbin/nologin
abrt x /sbin/nologin
rpcuser x /sbin/nologin
nfsnobody x /sbin/nologin
haldaemon x /sbin/nologin
ntp x /sbin/nologin
saslauth x /sbin/nologin
postfix x /sbin/nologin
sshd x /sbin/nologin
tcpdump x /sbin/nologin
oprofile x /sbin/nologin
mysql x /sbin/nologin
End of report
[root@localhost etc]#
控制語句:
語法:if (condition) {then-body} else {[ else-body]}
awk -F: '{if ($1=="root") print $1, "Admin"; else print $1,"Common User"}' /etc/passwd
[root@localhost etc]# awk -F: '{if ($1=="root") printf "%-15s: %s\n",$1,"Admin";else printf "%-15s: %s\n",$1,"Common User"}' /etc/passwd
root : Admin
bin : Common User
daemon : Common User
adm : Common User
lp : Common User
sync : Common User
shutdown : Common User
halt : Common User
mail : Common User
uucp : Common User
operator : Common User
games : Common User
gopher : Common User
ftp : Common User
nobody : Common User
dbus : Common User
vcsa : Common User
rpc : Common User
abrt : Common User
rpcuser : Common User
nfsnobody : Common User
haldaemon : Common User
ntp : Common User
saslauth : Common User
postfix : Common User
sshd : Common User
tcpdump : Common User
oprofile : Common User
mysql : Common User
-v聲明一個變量
[root@localhost etc]# awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd
1
30:00
while語句
語法:while (condition){statement1;statement2;...}
awk -F: '{i=1;while (i<3) {print $i;i++}}' /etc/passwd 循環每一個字段,
length 字符長度
顯示字符長度大於4的每一個字段
i<=NF遍歷每一行的所有字段,length($i)>=4 找出字段長度大於4的所有字段
[root@localhost ~]# awk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i} i++}}' /etc/passwd
取出以下大於10%使用率的
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda5 18G 1.9G 15G 12% /
tmpfs 491M 0 491M 0% /dev/shm
/dev/sda1 194M 29M 155M 16% /boot
/dev/sda3 985M 18M 918M 2% /home
[root@localhost ~]#
do-whlie 先直行一段然後循環。
語法: do {statement1,statement2,...}while (condtion)
awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd
for
語法for ( variable assignment;condition;iteration process) {statement1,statment2,...}
awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd
[root@localhost ~]# awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd
case
語法:switch (expression) { case VALUE or /REGEXP/: statement1,statement2,...default: statement1,...}
break和continue
continue提前進入下一個字段的循環
常用語循環或case語句中
next
提前結束對本行文本的處理,並接着處理下一行;列如下面的命令顯示ID號爲奇數的用戶
[root@localhost ~]# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
bin 1
adm 3
sync 5
halt 7
operator 11
gopher 13
nobody 99
dbus 81
vcsa 69
abrt 173
rpcuser 29
saslauth 499
postfix 89
awk中使用數組
array[index-expression]
index-expression可以使用任意字符串:需要注意的是,如果某數據組元素事先不存在,那麼在引用時,awk會自動創建此元素並初始化爲空串;因此需要判斷數組中是否存在元素,需要使用index in array的方式
要遍歷數組中的每一個元素,需要使用如下的特殊結構;
for (var in array) {statement1,...}
其中,var用於引用數組下標,而不是元素值;
[root@localhost ~]# awk -F: '{shell [$NF]++}END {for(A in shell){print A, shell[A]}}' /etc/passwd
/sbin/shutdown 1
/bin/bash 2
/sbin/nologin 24
/sbin/halt 1
/bin/sync 1
shell[/bin/bash]++
shell[/sbin/nologin]++
第一個元素從0開始第一行的$7下標爲/bin/bash ,然後++
第二個元素的下標爲第二行的$7下標爲/sbin/nologin ....
最後遍歷每一行,然後統計每一個shell有多少用戶
統計每一種狀態所出現的次數
[root@localhost ~]# netstat -ant |awk '/^tcp/ {STATE[$NF]++} END {for (a in STATE) print a,STATE[a]}'
ESTABLISHED 1
LISTEN 10
[root@localhost ~]# awk '{counts[$1]++};END { for (url in counts) print counts[url],url}' /var/log/httpd/access_log
刪除數組變量
從關係數組中刪除數組索引需要使用delete命令,使用格式爲:
delete array[index]