2021-05-12 14:32:11
Linux高階文字處理之gawk變數的操作符
一、變數
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模式的其他形式:
-
empy:空模式,匹配所有行
-
關係表示式,表示式結果非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 |
本文永久更新連結地址:http://www.linuxidc.com/Linux/2017-02/140318.htm
相關文章