歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux高級文本處理之gawk變量的操作符

Linux高級文本處理之gawk變量的操作符

日期:2017/2/28 13:43:45   编辑:Linux教程

一、變量

Awk 變量以字母開頭,後續字符可以是數字、字母、或下劃線。關鍵字不能用作 awk 變量。awk 變量可以直接使用而不需事先聲明。 如果要初始化變量,最好在BEGIN 區域內做,它只會執行一次。Awk 中沒有數據類型的概念,一個 awk 變量是 number 還是 string 取決於該變量所處的上下文。

實例1:使用”total”便是用戶建立的用來存儲公司所有雇員工資總和的變量。

[root@localhost ~]# cat emp4
101,John Doe,CEO,10000
102,Jason Smith,IT Manager,5000
103,Raj Reddy,Sysadmin,4500
104,Anand Ram,Developer,4500
105,Jane Miller,Sales Manager,3000

[root@localhost ~]# cat emp.awk 
BEGIN{
        FS=",";
        total=0;
}

{
        print $2 "'s salary is:" $4;
        total=total+$4;
}

END{
        print "---\nTotal company salary=$"total;
}

[root@localhost ~]# awk -f emp.awk emp4
John Doe's salary is:10000
Jason Smith's salary is:5000
Raj Reddy's salary is:4500
Anand Ram's salary is:4500
Jane Miller's salary is:3000
---
Total company salary=$27000

awk自定義變量的方法:

1.借助-v選項,可以將外部值(並非來自stdin)傳遞給awk

實例2:

1 2 3 4 5 6 [root@localhost ~]# awk -v var="young" 'BEGIN{print var,"\n","---"}{print var}' ./num young --- young young young

2.通過VAR=value的方式定義

實例3:

1 2 3 4 [root@localhost ~]# awk '{print v1,v2}' v1="young" v2="geek" ./num young geek young geek young geek

二、一元操作符

1.取正取反

只接受單個操作數的操作符叫做一元操作符。

實例1:取反操作

[root@localhost ~]# cat emp4
101,John Doe,CEO,10000
102,Jason Smith,IT Manager,5000
103,Raj Reddy,Sysadmin,4500
104,Anand Ram,Developer,4500
105,Jane Miller,Sales Manager,3000
[root@localhost ~]# awk -F, '{print -$4}' emp4
-10000
-5000
-4500
-4500
-3000

注意:取反只對數值類數據生效,字符串取反結果全部為0.

實例2:

[root@localhost ~]# cat num
-1
-2
-3
[root@localhost ~]# awk '{print +$1}' num
-1
-2
-3
[root@localhost ~]# awk '{print -$1}' num 
1
2
3

2.自增自減

VAR1=++VAR或者VAR1=--VAR,表示VAR先增加或者減去1再賦值給VAR1,VAR1=VAR++或VAR1=VAR--,表示先將VAR賦值給VAR1,VAR再增減或者減去1.

實例1:前自加子減

[root@localhost ~]# awk -F, '{print ++$4}' emp4 #前自加
10001
5001
4501
4501
3001
[root@localhost ~]# awk -F, '{print --$4}' emp4  #前自減
9999
4999
4499
4499

實例2:後自加子減

[root@localhost ~]# awk -F, '{$4--;print $4}' emp4  #後自減
9999
4999
4499
4499
2999
[root@localhost ~]# awk -F, '{$4++;print $4}' emp4  #後自加
10001
5001
4501
4501
3001

實例3:打印所有可登陸 shell 的用戶總數:

[root@localhost ~]# awk -F':' 
>'$NF ~ /\/bin\/bash/ { n++ }
> END { print n }' /etc/passwd
10

[root@localhost ~]# grep -c '/bin/bash$' /etc/passwd
10

實例4:

[root@localhost ~]# cat num
1
2
1
1
3
4
2
[root@localhost ~]# awk '/1/{print NF}' num
1
1
1
[root@localhost ~]# awk '/1/{n++}END{print n}' num        
3
[root@localhost ~]# awk '/2/{n++}END{print n}' num 
2
[root@localhost ~]# awk '/3/{n++}END{print n}' num 
1
[root@localhost ~]# awk '/4/{n++}END{print n}' num 
1

三、算術運算符

需要兩個操作數的操作符,成為二元操作符。 Awk 中有多種基本二元操作符(如算術操作符、 字符串操作符、賦值操作符,等等)。

實例1:將每件單獨的商品價格減少 20% 並且將每件單獨的商品的數量減少 1

[root@localhost ~]# cat items.txt 
101,HD Camcorder,Video,210,10
102,Refrigerator,Appliance,850,2
103,MP3 Player,Audio,270,15
104,Tennis Racket,Sports,190,20
105,Laser Printer,Office,475,5
[root@localhost ~]# cat dis.awk 
BEGIN{
FS=",";
OFS=",";
discount=0
}
{
discount=$4*20/100;
print $1,$2,$3,$4-discount,$5-1
}
[root@localhost ~]# awk -f dis.awk items.txt 
101,HD Camcorder,Video,168,9
102,Refrigerator,Appliance,680,1
103,MP3 Player,Audio,216,14
104,Tennis Racket,Sports,152,19
105,Laser Printer,Office,380,4

實例2:只打印偶數行

[root@localhost ~]# awk 'NR%2==0' items.txt                 
102,Refrigerator,Appliance,850,2
104,Tennis Racket,Sports,190,20

四、字符串操作符

(空格)是連接字符串的操作符。

實例1:

[root@localhost ~]# cat str.awk 
BEGIN{

        FS=",";
        OFS=",";
        str1="Audio";
        str2="Video";
        nustr="100";
        str3=str1 str2;
        print "Concatenate string is:"str3;
        nustr=nustr+1;
        print "Str to nu:"nustr;
}
[root@localhost ~]# awk -f str.awk items.txt 
Concatenate string is:AudioVideo
Str to nu:101

四、賦值操作符

實例1:

[root@localhost ~]# cat fz.awk 
BEGIN {
FS=",";
OFS=",";
total1 = total2 = total3 = total4 = total5 = 10;
total1 += 5; print total1;
total2 -= 5; print total2;
total3 *= 5; print total3;
total4 /= 5; print total4;
total5 %= 5; print total5;
}
[root@localhost ~]# awk -f fz.awk items.txt 
15
5
50
2
0

實例2:打印商品清單

[root@localhost ~]# cat items.txt 
101,HD Camcorder,Video,210,10
102,Refrigerator,Appliance,850,2
103,MP3 Player,Audio,270,15
104,Tennis Racket,Sports,190,20
105,Laser Printer,Office,475,5  

[root@localhost ~]# awk -F, '
>BEGIN{ total=0} { total +=$5 } 
>END { print "Total Qutantity:" total }' items.txt
Total Qutantity:52

五、比較操作符

實例1:打印數量小於等於臨界值 5 的商品信息

[root@localhost ~]# awk -F, '$5<=5' items.txt         
102,Refrigerator,Appliance,850,2
105,Laser Printer,Office,475,5

實例2:打印編號為 103 的商品信息

[root@localhost ~]# awk -F, '$1==103' items.txt 
103,MP3 Player,Audio,270,15

實例3:打印除 Video 以外的所有商品

[root@localhost ~]# awk -F, '$3!="Video"' items.txt 
102,Refrigerator,Appliance,850,2
103,MP3 Player,Audio,270,15
104,Tennis Racket,Sports,190,20
105,Laser Printer,Office,475,5

實例4:同實例3,但只打印描述信息

[root@localhost ~]# awk -F, '$3!="Video"{print $2}' items.txt 
Refrigerator
MP3 Player
Tennis Racket
Laser Printer

實例5:打印價錢低於 900 或者數量小於等於臨界值 5 的商品信息

[root@localhost ~]# awk -F, '$5<=5||$4<900' items.txt 
101,HD Camcorder,Video,210,10
102,Refrigerator,Appliance,850,2
103,MP3 Player,Audio,270,15
104,Tennis Racket,Sports,190,20
105,Laser Printer,Office,475,5

實例6:打印/etc/password 中最大的 UID(以及其所在的整行)。

[root@localhost ~]# awk -F ':' '
>$3 > maxuid 
>{ maxuid = $3; maxline = $0 } 
>END { print maxuid,maxline }' /etc/passwd
1009 user3:x:1009:1010::/home/user3:/bin/bash

實例8:打印/etc/passwd 中 UID 和 GROUP ID 相同的用戶信息

[root@localhost ~]# awk -F ':' '$3 == $4' /etc/passwd
root:x:0:0:young,geek,010110110,0101101101:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin

實例9:打印/etc/passwd 中 UID >= 100 並且用戶的 shell 是/bin/sh 的用戶

[root@localhost ~]# awk -F: '$3 >= 100 && $7 == "/bin/sh"' /etc/passwd 
user1:x:800:800:test user:/none:/bin/sh

或者:

[root@localhost ~]# awk -F ':' '$3 >= 100 && $NF ~ /\/bin\/sh/' /etc/passwd
user1:x:800:800:test user:/none:/bin/sh       #正則表達式模式匹配

實例10:打印/etc/passwd 中沒有注釋信息(第 5 個字段)的用戶

[root@localhost ~]# awk -F: '$5 == ""' /etc/passwd
abrt:x:173:173::/etc/abrt:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
sys:x:498:1001::/home/sys:/bin/bash
natasha:x:1006:1007::/home/natasha:/bin/bash
harry:x:1007:1008::/home/harry:/bin/bash
sarah:x:497:497::/home/sarah:/bin/nologin

實例11:使用取反(!)運算符打印奇數行

1 2 3 4 5 6 [root@localhost ~]# seq 10 | awk 'i=!i' 1 3 5 7 9

實例12:打印偶數行

1 2 3 4 5 6 [root@localhost ~]# seq 10 | awk -v i=1 'i=!i' 2 4 6 8 10

六、正則表達式操作符

實例1:

[root@localhost ~]# cat items.txt 
101,HD Camcorder,Video,210,10
102,Refrigerator,Appliance,850,2
103,MP3 Player,Audio,270,15
104,Tennis Racket,Sports,190,20
105,Laser Printer,Office,475,5
[root@localhost ~]# awk -F, '$2 == "Tennis"' items.txt  #精確匹配
[root@localhost ~]# awk -F, '$2 ~ "Tennis"' items.txt   #模糊匹配
104,Tennis Racket,Sports,190,20

實例2:

[root@localhost ~]# awk -F, '$2 !~ "Tennis"' items.txt  #不匹配
101,HD Camcorder,Video,210,10
102,Refrigerator,Appliance,850,2
103,MP3 Player,Audio,270,15
105,Laser Printer,Office,475,5

實例3:打印 shell 為/bin/bash 的用戶的總數,如果最後一個字段包含”/bin/bash”,則變量n 增加 1

[root@localhost ~]# grep -c '/bin/bash' /etc/passwd                                     
9
[root@localhost ~]# awk -F: '$NF ~ /\/bin\/bash/ { n++ } END{ print n}' /etc/passwd
9

補充說明:

awk PATTERN模式的其他形式:

  1. empy:空模式,匹配所有行

  2. 關系表達式,表達式結果非0為真,則執行後面body中語句;0則為假,不執行。例如

1 awk -F: '$3>=500{print $1,$3} ' /etc/passwd

3.行范圍,類似sed或vim中的地址定界:

1 /start pattern/,/end pattern/

注意:不支持直接給出數字格式

實例:

1 2 3 4 5 6 7 8 9 10 [root@localhost ~]# awk '/^root/,/^mail/{print $0}' /etc/passwd root:x:0:0:young,geek,010110110,0101101101:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
Copyright © Linux教程網 All Rights Reserved