日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

awk快速入门

發布時間:2024/4/17 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 awk快速入门 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

AWK快速入門

awk簡介

awk是一個優良的文本處理工具,是Linux中文本三劍客之一,awk的名字取自于其創始人Alfred Aho、Peter Weinberger和Brain Kernighan三人姓式的首字母。
awk的功能及其強大,可以進行式樣裝入、流控制、數學運算符、進程控制語句甚至內置的變量和函數,他具備了一個完整語言所應有的幾乎所有特性。

awk語法

awk程序由BEGIN語句塊、能夠使用模式匹配的通用語句塊、END語句塊,共3部分組成

awk [option] '[BEGIN{action;...}]pattern{action;...}[END{action;...}]' file 選項說明
-F指定分隔符
-f指定awk程序文件
-v變量賦值,每個變量都需要使用-v var=value來賦值

awk工作原理

1.執行BEGIN{action;...}語句塊中的語句
BEGIN語句塊在awk開始從輸入流中讀取的行之前被執行,這是個可選的語句塊,
2.從文件或標準輸入中讀取一行,然后執行pattern{action;...}語句塊,它逐行掃描文件,從第一行到最后一行重復這個過程,直到文件全部被讀取完畢。
3。當讀至輸入流末尾時,執行END{action;...}語句塊。
END語句塊,在awk從輸入流種讀取完所有的行之后再執行,比如打印所有行的分析結果這里信息匯總都是在END語句中完成,它也是個可選語句塊

awk基本用法

awk最簡單的使用方法為:

awk [option] 'pattern{action;...}' file

一、print

print的參數可以是變量、數值或字符串。字符串必須用雙引號引用,參數用逗號分隔。如果沒有逗號,參數就串聯在一起,無法區分。這里逗號的作用與輸出文件的分隔符所用是一樣的,只是后者是空格而已。當pattern不指定時默認打印文件中所有的行。
示例1:打印/etc/fstab中的每一行

[root@centos7 ~]# awk '{print $0}' /etc/fstab# # /etc/fstab # Created by anaconda on Tue Mar 5 21:07:19 2019 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # UUID=45490aa4-cf29-420d-a606-af32688b6707 / xfs defaults 0 0 UUID=15dcd896-b7cf-48d0-b8bd-4c0b0f2c62b2 /boot xfs defaults 0 0 UUID=4b6e1813-2c46-402a-869a-02cbbcb76ade /data xfs defaults 0 0 UUID=0995b444-48c1-4423-92bc-2deda0d3c082 swap swap defaults 0 0

二、awk變量

awk有內置變量和自定義變量
內置變量有FS、OFS、RS、ORS、NF、FNR、FILENAME、ARGC、ARGV

1.FS:設置輸入域分隔符,等價于命令行選項-F

示例1:使用變量FS指定分隔符,取出/etc/fstab的第1第3列

[root@centos7 ~]# awk -v FS=: '{print $1,$3}' /etc/passwd root 0 bin 1 daemon 2 ...以下省略...

示例2:使用選項-F指定分隔符,取出/etc/fstab的第1第3列

[root@centos7 ~]# awk -F":" '{print $1,$3}' /etc/passwd root 0 bin 1 daemon 2 ...以下省略...

示例3:用正則表達式當分隔符取出分區利用率

[root@centos7 ~]# df | awk -F"[[:space:]]+|%" '{print $5}' Use 15 0 0 2 0 1 17

示例4:變量在action中也能被引用,在第一個域和第3個域之間加:號

[root@centos7 ~]# awk -v FS=: '{print $1,FS,$3}' /etc/passwd root : 0 bin : 1 daemon : 2 ...以下省略...

2.OFS:設置輸出時域分隔符,默認為空白

示例1:以:為分隔符分隔字段,輸出時以+++為分隔符,取出/etc/passwd第1第2字段

[root@centos7 ~]# awk -v FS=: -v OFS=+++ '{print $1,$2}' /etc/passwd root+++x bin+++x daemon+++x ...以下省略...

3.RS:設置記錄分隔符

當記錄的分割符指定為某符號時,從字符開始至記錄分隔符的字符串為一條記錄,記錄的條數和行數無關。
示例1:創建一個文本指定;為分隔符查看記錄情況。

[root@centos7 ~]# cat a.txt a,b,c;1,2,3,4,;aa,bb,cc zz,yy,xxx;122,444,2322;AA BB,CC

以上面文件內容為例,以分號為記錄的分隔符,此文件一共有5條記錄。

[root@centos7 ~]# awk -v RS=";" '{print $0}' a.txt a,b,c 1,2,3,4, aa,bb,cc #此行與下一行為一條記錄中間隱藏了一個換行符 zz,yy,xxx 122,444,2322 AA #此行與下一行為一條記錄中間隱藏了一個換行符 BB,CC

4.ORS:設置輸出時記錄分隔符

ORS變量指定輸出時的記錄分隔符為什么符號。
示例:
依舊為a.txt文件,設置分隔符為,號,紀錄分隔符為;號,輸出時設置記錄分分隔符為___,取出第一字段。

[root@centos7 ~]# cat a.txt a,b,c;1,2,3,4,;aa,bb,cc zz,yy,xxx;122,444,2322;AA BB,CC[root@centos7 ~]# awk -F, -v RS=";" -v ORS="___" '{print $1}' a.txt a___1___aa___122___AA BB___

5.NF:域數

NF可以查看一條記錄內有多少個域,也可以用來查看倒數第N個字符為什么
示例1:
以/etc/passwd為例,以:號為分隔符查看每行的字段數量

[root@centos7 ~]# awk -F: '{print NF}' /etc/passwd 7 7 7 ...以下省略...

示例2:
差看/etc/passwd文件內,以:為分隔符,倒數第2個字段的內容

[root@centos7 ~]# awk -F: '{print $(NF-1)}' /etc/passwd /root /bin /sbin ...以下省略...

6.NR:記錄數

NR變量為已讀文件的記錄數
示例1:
以;為記錄符,在a.txt的文件的每條記錄前加上記錄行。

[root@centos7 ~]# cat a.txt a,b,c;1,2,3,4,;aa,bb,cc zz,yy,xxx;122,444,2322;AA BB,CC [root@centos7 ~]# awk -v RS=";" '{print NR,$0}' a.txt 1 a,b,c 2 1,2,3,4, 3 aa,bb,cc zz,yy,xxx 4 122,444,2322 5 AA BB,CC

NR變量還可以合并計數多個文件的記錄
示例2:查看/etc/fstab和/etc/issue總共有多少記錄號

[root@centos7 ~]# awk '{print NR}' /etc/fstab /etc/issue 1 2 ...中間省略... 14 15

7.FNR:文件的記錄數

FNR變量為每個文件分別記錄記錄數。
示例:查看/etc/fstab和/etc/issue的記錄數

[root@centos7 ~]# awk '{print FNR}' /etc/fstab /etc/issue 1 2 ...中間省略... 11 12 1 2 3

8.FILENAME:文件名

FILENAME變量為輸出文件名
示例:在匹配到的行后面加上文件名

[root@centos7 ~]# awk '{print $0,FILENAME}' /etc/passwd root:x:0:0:root:/root:/bin/bash /etc/passwd bin:x:1:1:bin:/bin:/sbin/nologin /etc/passwd daemon:x:2:2:daemon:/sbin:/sbin/nologin /etc/passwd ...以下省略...

9.ARGC:命令行參數個數

ARGC變量存放的為參數個數。
示例:

[root@centos7 ~]# awk '{print ARGC}' /etc/issue 2 2 2

顯示為2個參數,是哪兩個參數呢?看下面那個函數

10.ARGV:查看命令行參數

ARGV變量為一個數組里面存放的為awk的每個參數
示例:
打印每一個參數

[root@centos7 ~]# awk '{print ARGV[1]}' /etc/issue /etc/issue /etc/issue /etc/issue [root@centos7 ~]# awk '{print ARGV[0]}' /etc/issue awk awk awk

自定義變量
自定義變量的賦值有2種方法

1.-v var=value

示例1:輸出變量在每行

[root@centos7 ~]# awk -v title=ceo -F: '{print title":"$1}' /etc/passwd ceo:root ceo:bin ceo:daemon ceo:adm ceo:lp

2.可以直接在program中直接定義

把變量賦值放在{}內,把變量放在{}內賦值時變量值必須要加雙引號,變量必須先賦值再引用,次序錯誤會導致第一次匹配到的行沒有值
示例1:在每個用戶前加上ceo

[root@centos7 ~]# awk -F: '{title="ceo"; print title":"$1}' /etc/passwd ceo:root ceo:bin ceo:daemon ceo:adm ceo:lp ceo:sync

示例2:調用腳本文件
awk '{action}' 單引號內的腳本可以存放在文件內被調用

[root@centos7 ~]# cat 2.txt {title="ceo";print title":"$1} [root@centos7 ~]# awk -F: -f 2.txt /etc/passwd ceo:root ceo:bin ceo:daemon

三、printf

printf格式化輸出:

printf "FORMAT" ,item1,item2,... 使用printf時,需要注意以下3點:
1.使用printf時必須指定FORMAT,
2.printf不會自動換行,需要顯式給出換行控制符\n
3.FORMAT中需要分別為后面每個item指定格式符
printf的格式符有以下:
格式符說明
%c顯示字符的ASCII碼
%d,%i顯示十進制整數
%e,%E顯示科學計數法數值
%f顯示浮點數
%g以科學計數法或浮點形式顯示數值
%s顯示字符串
%u無符號整數
%%顯示%自身
printf中除了格式符還有修飾符:
修飾符說明
#[.#]第一個數字控制顯示的寬度;第二個#標識小數點后精度,%3.1f
-左對齊(默認為右對齊)%-15s
+顯示數值的正負值符號%+d

示例1:
%d打印整數

[root@centos7 ~]# echo 100.222 | awk '{printf "this is %d" ,$0"\n"}' this is 100

示例2:
格式符有幾個對應的item項就要就幾個否則語法錯誤

[root@centos7 ~]# echo "123.455 221.245" | awk '{printf "this is %d %d" ,$1,$2}' this is 123 221

示例3:
%f可以打印小數,默認輸出的為6位。也可以指定小數位。

[root@centos7 ~]# echo "123.455 221.245" | awk '{printf "this is %f" ,$1}' this is 123.455000 #指定小數位用法 [root@centos7 ~]# echo "123.455 221.245" | awk '{printf "this is %.3f" ,$1}' this is 123.455

示例4:
.之前的數字為長度(默認右對齊)

[root@centos7 ~]# echo "123.455 221.245" | awk '{printf "this is %10.3f %10.3f" ,$1,$2}' this is 123.455 221.245

示例5:
指定左對齊,在%后面加上-

[root@centos7 ~]# echo "123.222 345.23" |awk '{printf "this is %-10.3f %-10.3f",$1,$2}' this is 123.222 345.230

四、操作符

awk還支持各種操作符如算數操作符、字符串操作符、賦值操作符、比較操作符、模式匹配操作符

1.算數操作符

算數操作符有+、-、、/、^、%,如:
x+y,x-y,xy,x/y,x^y,x%y
示例1:
簡單的算術運算

[root@centos7 ~]# awk 'BEGIN{I=20;J=10;M=I+J;print M}' 30

示例2:
-x:轉換為負數

[root@centos7 ~]# awk 'BEGIN{I=20;I=-I;print I}' -20

2.賦值操作符:

賦值操作符有:=,+=,-=,*=,/=,%=,^=,++,--
示例1:

[root@centos7 ~]# awk 'BEGIN{I=10;I+=2;print I}' 12 [root@centos7 ~]# awk 'BEGIN{I=10;I-=2;print I}' 8 [root@centos7 ~]# awk 'BEGIN{I=10;I*=2;print I}' 20

3.比較操作符和模式匹配符

比較操作符和模式匹配符常用在awk的行過濾pattern中,Pattern為空時所有都符合條件
pattern中可以添加比較符號和模式匹配
比較符號有:==(等于),!=(不等于),>(大于),>=(大于等于),<(小于),<=(小于等于)
模式匹配符:~(符號左邊內容是否右邊匹配內容,包含內容),!~(符號左邊內容的是否不匹配右邊內容)
模式匹配時可以使用正則表達式!
3.1比較操作符示例
示例1:
取出連接主機的IP

[root@centos7 ~]# ss -tn | awk -F" +|:" 'NR>1{print $(NF-2)}' 192.168.172.1

示例2:
取出用戶列表中UID大于1000的用戶和ID

[root@centos7 ~]# awk -F: '$3>1000{print $1,$3}' /etc/passwd nfsnobody 65534

示例3:
取出ip地址

[root@centos7 ~]# ifconfig | awk 'NR==2{print $2}' 192.168.172.129

示例4:
取出分區利用率大于10的設備

[root@centos7 ~]# df | awk -F" +|%" '/\/dev\/sd/ && $5>10{print $1,$5}' /dev/sda1 17

3.2模式匹配示例
示例1:匹配第一列為/dev/sd開頭行

[root@centos7 ~]# df | awk '/\/dev\/sd/{print $1}' /dev/sda2 /dev/sda3 /dev/sda1

示例2:匹配/etc/fstab非#開頭的行

[root@centos7 ~]# awk '!/^#/' /etc/fstab UUID=45490aa4-cf29-420d-a606-af32688b6707 / xfs defaults 0 0 UUID=15dcd896-b7cf-48d0-b8bd-4c0b0f2c62b2 /boot xfs defaults 0 0 UUID=4b6e1813-2c46-402a-869a-02cbbcb76ade /data xfs defaults 0 0 UUID=0995b444-48c1-4423-92bc-2deda0d3c082 swap swap defaults 0 0

4.邏輯操作符

邏輯操作符:與&&,或||,非!
示例1:
取出/etc/passwd非nologin結尾的行

[root@centos7 ~]# awk '!/nologin$/' /etc/passwd root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt masuri:x:1000:1000:masuri:/home/masuri:/bin/bash

示例2:
取出分區利用率大于10的設備名和分區利用率

[root@centos7 ~]# df | awk -F" +|%" '/\/dev\/sd/ && $5>10{print $1,$5}' /dev/sda1 17

示例3:
取出連接數前3的IP地址

[root@centos7 ~]# netstat -tn | awk -F" +|:" '/ESTABLISHED/{print $6}' | sort | uniq -c | sort -nr | head -3

5.三目表達式

三目表達式格式:
selector?if-ture-expression:if-false-expression
判斷selector是否為真,如果為真則執行if-ture語句,不為真則執行if-false語句。
示例1:
在Uid大于等于1000的用戶前添加commom user,小于1000的添加system user

[root@centos7 ~]# awk -F: '$3>=1000?USER="COMMOM USER:":USER="SYSTEM USER:"{print USER$1}' /etc/passwd SYSTEM USER:root SYSTEM USER:bin ...中間省略... SYSTEM USER:ntp SYSTEM USER:tcpdump COMMOM USER:masuri

五、PATTERN部分總結

PATTEN:awk在執行時會根據pattern條件,過濾匹配的行,再做處理。
pattern的條件可以有以下幾種:

1.空

如果pattern部分為空,則默認匹配每一行
示例:打印所有行

[root@centos7 ~]# awk '{print $0}' /etc/fstab# # /etc/fstab # Created by anaconda on Tue Mar 5 21:07:19 2019 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # UUID=45490aa4-cf29-420d-a606-af32688b6707 / xfs defaults 0 0 UUID=15dcd896-b7cf-48d0-b8bd-4c0b0f2c62b2 /boot xfs defaults 0 0 UUID=4b6e1813-2c46-402a-869a-02cbbcb76ade /data xfs defaults 0 0 UUID=0995b444-48c1-4423-92bc-2deda0d3c082 swap swap defaults 0 0

2.正則表達式

/regular expression/:僅處理能夠被模式匹配到的行,需要用//括起來
示例:找出/etc/passwd中以g開頭的行的第1字段和第3字段

[root@centos7 ~]# awk -F: '/^g/{print $1,$3}' /etc/passwd games 12 gluster 993 geoclue 992 gdm 42 gnome-initial-setup 989

3.關系表達式

relational expression: 關系表達式,結果為“真”才會被處理
真和假的定義:
3.1真:結果為非0值,非空字符串
示例1: 當有值時為真,輸出所有。

[root@centos7 ~]# seq 3 | awk '2' 1 2 3

示例2:當數字為負數時,輸出也為真

[root@centos7 ~]# seq 3 | awk '"-1"' 1 2 3

示例3:當中間的數字為空格時也為真

[root@centos7 ~]# seq 3 | awk '" "' 1 2 3

3.2假:結果為空字符串或0值,假則不會被處理
示例1:當值為空和0時不做輸出

[root@centos7 ~]# seq 5 | awk '""' [root@centos7 ~]# seq 5 | awk '0' [root@centos7 ~]#

示例2:在awk中不加字符不添加雙引號表示為變量,變量為空和0時也為假,變量中有值時為真

[root@centos7 ~]# seq 5 | awk 'i' #變量中沒有值,假 [root@centos7 ~]# seq 5 | awk -v i=1 'i' #變量中有值,真,輸出結果 1 2 3 4 5

4.行范圍

pattern可以使用行范圍進行匹配
/pat1/,/pat2/ 不支持直接給出數字格式
示例:打印b開頭的行到f開頭的行

[root@centos7 ~]# awk '/^b/,/^f/' /etc/passwd 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 operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

5.BEGIN/END模式

BEGIN{}:僅在開始處理文件中的文本之前執行一次
END{}:僅在文本處理完成之后執行一
示例1:使用BEGIN來添加表頭,做格式化輸出。

[root@centos7 ~]# awk -F: 'BEGIN{print "|USERNAME |UID\n------------------------------------"}{printf "|%-30s |%-10d\n--------------------------------------\n",$1,$3}' /etc/passwd |USERNAME |UID ------------------------------------ |root |0 -------------------------------------- |bin |1 -------------------------------------- |daemon |2 -------------------------------------- |adm |3 -------------------------------------- |lp |4 -------------------------------------- |sync |5 -------------------------------------- |shutdown |6

六、awk控制語句

流程控制語句是任何程序設計語言都不能缺少的部分。任何好的語言都有一些執行流程控制的語句。awk提供的完備的流程控制語句類似于C語言,這給我們編程帶來了極大的方便。
awk控制語句有:if-else,while循環,do-while循環,for循環,break,continue,delete array[index],delete array,exit

1.if-else

使用場景:對awk取得的整行或某個字段做條件判斷
語法:

if(condition){statement;…}[else statement] if(condition1){statement1}else if(condition2){statement2}else{statement3}

示例:1.打印出/etc/passwd下uid大于1000的行

[root@centos7 ~]# awk -F: '{if($3>1000)print $0}' /etc/passwd nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

示例2:如果Uid為偶數則打印出uid和用戶名

[root@centos7 ~]# awk -F: '{if($3%2==0)print $1,$3}' /etc/passwd root 0 daemon 2 lp 4 shutdown 6 mail 8 games 12 ftp 14 systemd-network 192 libstoragemgmt 998 rpc 32 saslauth 996 rtkit 172 nfsnobody 65534 unbound 994 geoclue 992 saned 990 gdm 42 sshd 74 avahi 70 ntp 38 tcpdump 72 masuri 1000

示例3:考試成績判斷,60及格,80分還行,80分以上真棒,60以下不及格

[root@centos7 ~]# awk -v score=80 'BEGIN{if(score<60){print "no pass"}else if(score<=80){print "just so so"}else if(score>80){print "good"}}' just so so

2.while循環

使用場景:
1.對一行內的多個字段逐一類似處理時使用
2.對數組中的各元素逐一處理時使用
語法:

while(condition){statement;...}

條件為真進入循環,條件為假退出循環。
示例1:打印/etc/password第一行每一字段的長度

[root@centos7 ~]# awk -F: 'NR==1{i=1;while(i<=NF){print $i,length($i);i++}}' /etc/passwd root 4 x 1 0 1 0 1 root 4 /root 5 /bin/bash 9

示例2:取出最大值和最小值

[root@centos7 ~]# awk -F, '{max=$1;mix=$1;i=1;while(i<=NF){if($i>max){max=$i};if($i<mix){mix=$i};i++};print mix,max}' test1 207 31976

示例3:1+2+3+..+100

[root@centos7 ~]# awk 'BEGIN{i=1;while(i<=100){sum+=i;i++}print sum}' 5050

3.for循環

常用語法:

for(expr1;expr2;expr3){statement;...}

特殊用法:便利數組中的元素
語法:

for(i in arrary){for body}

示例1:for循環1+到100

[root@centos7 ~]# awk 'BEGIN{for(i=1;i<=100;i++){sum+=i}print sum}' 5050

4.break和continue

break為提前結束循環
continue為提前結束本次循環,進入下一次循環
示例:將1到100的偶數相加

[root@centos7 ~]# awk 'BEGIN{for(i=1;i<=100;i++){if(i%2==0){sum+=i}}print sum}' 2550

1-100的偶數相加,當i=50時跳出不加,繼續執行后續循環

[root@centos7 ~]# awk 'BEGIN{for(i=1;i<=100;i++){if(i==50){continue};if(i%2==0){sum+=i}}print sum}' 2500

1-100的偶數相加,當i=50時跳出所有循環

[root@centos7 ~]# awk 'BEGIN{for(i=1;i<=100;i++){if(i==50){break};if(i%2==0){sum+=i}}print sum}' 600

5.next

next是提前結束對本行的處理直接進入下一行的處理,next跳出的是awk自身的循環。
示例:
打印Uid為偶數的行

[root@centos7 ~]# awk -F: '{if($3%2==!0){next}print $1,$3}' /etc/passwd root 0 daemon 2 lp 4 shutdown 6 mail 8 games 12 ftp 14 systemd-network 192 libstoragemgmt 998 rpc 32 saslauth 996 rtkit 172 nfsnobody 65534 unbound 994 geoclue 992 saned 990 gdm 42 sshd 74 avahi 70 ntp 38 tcpdump 72 masuri 1000

七、awk數組

awk數組為關聯數組:array[index-expression]
index-expression為數組下標
數組在使用時需注意以下幾點:
1.數組下標可使用任意字符串;字符串要使用雙引號括起來
2.如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其初始化為“空串”
3.若要判斷數組中是否存在某元素,要時用“index in array”格式進行遍歷

示例:給數組賦值,和輸出數組

[root@centos7 ~]# awk 'BEGIN{arr["ceo"]="mage";arr["cto"]="laowang";print arr["ceo"]}' mage [root@centos7 ~]# awk 'BEGIN{arr["ceo"]="mage";arr["cto"]="laowang";print arr["cto"]}' laowang

若要遍歷數組中的每個元素,要使用for循環

for(var in array){for-body}

注意:var會遍歷arry的每個索引
示例:遍歷數組,可以先將數組下標賦給i

[root@centos7 ~]# awk 'BEGIN{arr["ceo"]="mage";arr["cto"]="laowang";for(i in arr){print arr[i]}}' mage laowang

示例2:數組的其他用法:去重
創建一個文件輸入以下內容,然后執行awk命令

[root@centos7 ~]# cat f1.txt aa bb cc aa 11 22 11 [root@centos7 ~]# awk '!line[$0]++' f1.txt aa bb cc 11 22

此方法比較繞,讀入第一行aa作為數組line的下標,此時數組內的值為空“假”取反后為真打印此行,然后再執行++,此時line內的值為1,當再次遇到aa的行時,數組line[aa]內有值1,取反后為假不輸出,然后再++此時[aa]內值為2
驗證:

[root@centos7 ~]# awk '{!line[$0]++;print $0,line[$0]}' f1.txt aa 1 bb 1 cc 1 aa 2 11 1 22 1 11 2

示例:數組的高級用法
取連接狀態數

[root@centos7 ~]# netstat -tna | awk '/^tcp/{state[$NF]++}END{for(i in state){print i,state[i]}}' #state[$NF]++表示將最后一個字段作為數組的下標,然后對里面的值+1,當再次遇到相同的下標時,再次加1 LISTEN 11 ESTABLISHED 1

統計每個ip的連接次數

[root@centos7 ~]# awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' access_log 172.20.0.200 1482 172.20.21.121 2 172.20.30.91 29 172.16.102.29 864 172.20.0.76 1565 172.20.9.9 15 172.20.1.125 463 172.20.61.11 2 172.20.73.73 198 172.20.107.222 3 172.20.0.222 2834 172.20.111.240 4

取出連接數排名前10的ip

[root@centos7 ~]# awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' access_log | sort -nr | head 4870 172.20.116.228 3429 172.20.116.208 2834 172.20.0.222 2613 172.20.112.14 2267 172.20.0.227 2262 172.20.116.179 2259 172.20.65.65 1565 172.20.0.76 1482 172.20.0.200 1110 172.20.28.145

小練習:
統計男女生的平均分數

namescoregender
a100m
b99f
c80m
d98f
[root@centos7 ~]# awk -F" +" 'NR>1{num[$3]++;sum[$3]+=$2}END{for(i in sum)print i,sum[i]/num[i]}' score m 90 f 98.5

八、字符串處理

1.length([s]):返回字符串的長度
示例:

[root@centos7 ~]# awk 'BEGIN{print length("abc")}' 3

2.sub(r,s,[t]):對t字符串搜索r表示的模式匹配的內容,并替換為s所表示的內容(只替換第一次匹配到的)
示例:

[root@centos7 ~]# echo "2008:08:08 08:08:08" | awk '{sub(/:/,"-",$1);print $0}' 2008-08:08 08:08:08

3.gsub(r,s,[t]):對t字符串搜索r表示的模式匹配的內容,并全部替換為s所表示的內容
示例:

[root@centos7 ~]# echo "2008:08:08 08:08:08" | awk '{gsub(/:/,"-",$1);print $0}' 2008-08-08 08:08:08

4.splits(s,arry,[r]):以r為分隔符,切割字符串,并將切割后的字符串保存至array做表示的數組中,第一個索引值為1,第二個索引值為2,...
示例:

[root@centos7 ~]# echo "2008:08:08 08:08:08" | awk '{split($0,arr,":");}END{for(i in arr){print i,arr[i]}}' 4 08 5 08 1 2008 2 08 3 08 08

用函數來實現ip連接次數

[root@centos7 ~]# awk '/^ESTAB/{split($NF,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}' ss.log 192.168.172.1 465

九、自定義函數

語法:

function name (parameter,parameter,...){statementsreturn experssion }

示例:
awk函數定義方法

[root@centos7 ~]# cat fun.awk #!/bin/awk -f function max(x,y){ #x,y為行參x>y?var=x:var=yreturn var } BEGIN{print max(a,b)} #a,b為實參

awk函數調用

[root@centos7 ~]# awk -v a=40 -v b=50 -f fun.awk 50 [root@centos7 ~]#

十、awk中調用shell命令

system命令:空格是awk中的字符串連接符,如果system中需要使用awk中的變量可以使用空格分隔,或者說除了awk的變量外其他一律用“”引用起來
示例1:調用系統命令

[root@centos7 ~]# awk 'BEGIN{system(hostname)}' [root@centos7 ~]# awk 'BEGIN{system("hostname")}' centos7.localdomain [root@centos7 ~]# awk 'BEGIN{system("echo hello")}' hello [root@centos7 ~]# awk 'BEGIN{system("ls")}' 1.txt access.log f1.txt initial-setup-ks.cfg ss.log access_log anaconda-ks.cfg fun.awk ss.lg test1 [root@centos7 ~]#

示例2:輸出變量的方法
調用雙引號輸出變量時,變量必須放在雙引號外,如果放在雙引號內,變量只會被當作字符輸出

[root@centos7 ~]# awk -v var=hello 'BEGIN{system("echo var")}' var [root@centos7 ~]# awk -v var=hello 'BEGIN{system("echo"var)}' #echo后必須有空格 sh: echohello: command not found [root@centos7 ~]# awk -v var=hello 'BEGIN{system("echo" var)}' #并且空格必須再雙引號內 sh: echohello: command not found [root@centos7 ~]# awk -v var=hello 'BEGIN{system("echo "var)}' hello

十一、awk腳本

awk腳本格式:
1.腳本后綴為.awk
2.腳本首行加上#!/bin/awk -f
3.給腳本添加執行權限
示例:

[root@centos7 ~]# cat test.awk #查看腳本內容 #!/bin/awk -f #this is test awk script {if($3>1000)print $1,$3} [root@centos7 ~]# chmod +x test.awk [root@centos7 ~]# ./test.awk -F: /etc/passwd nfsnobody 65534

十二、向awk腳本傳遞參數

使用格式:

awkfile var=value var2=value2 ... inputfile

注意:在BEGIN過程中不可用。直到首行輸入完成以后,變量才可用。可以通過-v參數,讓awk在執行BIGIN之前得到變量的值。命令行中每一個指定的變量都需要一個-v參數。
示例:
創建一個腳本,此處以上一個腳本為例進行修改。

[root@centos7 ~]# cat test.awk #查看腳本內容 #!/bin/awk -f #this is test awk script $3>=min && $3<=max{print $1,$3} #其中min和max為位置參數,$1,$3表示awk所要掃描的文件中的字段。此處以/etc/passwd為例,就是對應的用戶名和UID[root@centos7 ~]# ./test.awk -F: min=10 max=20 /etc/passwd #找出uid再10-20之間的行 operator 11 games 12 ftp 14

轉載于:https://blog.51cto.com/11886307/2378463

總結

以上是生活随笔為你收集整理的awk快速入门的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。