awk入門及進階

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]



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