- 工信部備案號 滇ICP備05000110號-1
- 滇公安備案 滇53010302000111
- 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證 B1.B2-20181647、滇B1.B2-20190004
- 云南互聯(lián)網(wǎng)協(xié)會(huì )理事單位
- 安全聯(lián)盟認證網(wǎng)站身份V標記
- 域名注冊服務(wù)機構許可:滇D3-20230001
- 代理域名注冊服務(wù)機構:新網(wǎng)數碼
1. 命令格式
gawk [OPTIONS] 'program' FILES....
program:'PATTERN{ACTION}'
一條awk命令中,PATTERN和ACTION,至少存在一個(gè)才可執行;
缺少PATTERN,則對輸入行內容全部執行ACTION;
缺少ACTION,則所有匹配上PATTERN的輸入行都會(huì )被輸出;
在awk中使用分號“;”來(lái)分割語(yǔ)句;
2. awk的執行過(guò)程
awk讀取一行,進(jìn)行模式匹配,匹配了就執行相應的動(dòng)作,沒(méi)有匹配就忽略,讀取下一行,重復此動(dòng)作.
3. 內置變量
FS:輸入文件的field分隔符,默認是空白字符;
OFS:輸出文件的field分隔符,默認是空白字符;
RS:輸入文件record分隔符,默認是\n;
ORS:輸入文件record分隔符,默認是\n;
NF:每行的field數量,{print NF}表示顯示當前行的field數量,{print $NF}表示顯示當前行的最后一個(gè)field;
NR:record數,對所有輸入行進(jìn)行統一排序;
FNR:record數,對每個(gè)文件的輸入行進(jìn)行分別排序;
FILENAME:輸入文件的名字;
ARGC:命令行中的參數個(gè)數;
ARGV:數組,可以將當前命令行中的參數分別加入到ARGV這個(gè)數組中,從0開(kāi)始;
$1、$2、$3...$n:代表當前行中對應的field
4. 常用OPTION
-F:指定輸入分隔符;
-v:指定awk的變量;像FS、OSF、RS、ORS這些變量,就可以使用-v進(jìn)行重新賦值;
5. 雙引號的作用
定義一個(gè)變量superuser的值為root,但是打印的時(shí)候,發(fā)現打印出了一個(gè)空行,并沒(méi)有實(shí)際內容
[root@CentOS7 ~]# awk 'BEGIN{superuser=root;print superuser}'
空行......
這是因為只有加上了雙引號才會(huì )被awk認為是字符串,否則會(huì )被認為是變量。在上面這個(gè)例子中,想要為superuser賦值的是root字符串,但是因為沒(méi)有加上雙引號,被awk認為root也是一個(gè)變量,但是awk中又不存在這個(gè)變量,所以最終為superuser的變量?jì)热菥褪强铡?/p>
所以在awk中定義變量應該是這種情況:
[root@centos7 ~]# awk 'BEGIN{superuser="root";print superuser}'
root
使用-v參數就沒(méi)有上面的限制
[root@centos7 ~]# awk -v superuser=root 'BEGIN{print superuser}'
root
6. ACTION
6.1 printf命令:按照指定的FORMAT進(jìn)行格式化輸出;
格式化輸出:printf FORMAT, item1, item2, ...
FORMAT:FORMAT是一個(gè)字符串, 它包含按字面打印的文本, 中間散布著(zhù)格式說(shuō)明符, 格式說(shuō)明符用于說(shuō)明如何打印值. 一個(gè)格式說(shuō)明符是一個(gè)%, 后面跟著(zhù)幾個(gè)字符, 這些字符控制一個(gè)value 的輸出格式. 第一個(gè)格式說(shuō)明符說(shuō)明item1 的輸出格式, 第二個(gè)格式說(shuō)明符說(shuō)明item2 的輸出格式, 依次類(lèi)推. 于是, 格式說(shuō)明符的數量應該和被打印的item 一樣多;
printf不會(huì )自動(dòng)產(chǎn)生換行符,必須手動(dòng)創(chuàng )建;
格式符
%s:顯示字符串;
%i,%d:顯示十進(jìn)制整數;
修飾符
#[.#]:第一個(gè)#控制顯示的寬度,第二個(gè)#表示小數點(diǎn)后的精度;
例如:%3.1f
-減號:左對齊(不加減號,默認為右對齊);
+加號:顯示數值的符號;
實(shí)例
例如:使用printf打印/etc/passwd中的$1和$3
[Allen@centos7 ~]$ head /etc/passwd | awk -F: '{printf "Username: %-12sUID: %-8i\n",$1,$3}'
Username: root UID: 0
Username: bin UID: 1
Username: daemon UID: 2
Username: adm UID: 3
Username: lp UID: 4
Username: sync UID: 5
Username: shutdown UID: 6
Username: halt UID: 7
Username: mail UID: 8
Username: operator UID: 11
6.2 if-else
語(yǔ)法:'if(condition){statements}[else{statements}]'
使用場(chǎng)景:對awk取得的整行或某個(gè)字段做條件判斷;
實(shí)例
例如:當$3大于等于1000時(shí),打印$1;
[Allen@centos7 ~]$ awk -F: '{if($3>=1000) printf "%s\n",$1}' /etc/passwd
Allen
logstash
例如:當$3大于等于1000時(shí),打印為CommonUser: $1;否則打印為Systemuser: $1;
[Allen@centos7 ~]$ awk -F: '{if($3>=1000) {printf "CommonUser: %-15s\n",$1} else {printf "SystemUser: %s\n",$1}}' /etc/passwd | head
SystemUser: root
SystemUser: bin
SystemUser: daemon
SystemUser: adm
SystemUser: lp
SystemUser: sync
SystemUser: shutdown
SystemUser: halt
SystemUser: mail
SystemUser: operator
6.3 while
語(yǔ)法:while(condition){statements}
使用場(chǎng)景:對一行內的多個(gè)字段逐一進(jìn)行類(lèi)似處理時(shí)使用;或對數組中的各元素逐一處理時(shí)使用;
實(shí)例
例如:以空格開(kāi)頭0次或多次,后跟linux16的行,以空格為分隔符,顯示每行中各字段的長(cháng)度;
[Allen@centos7 ~]$ sudo awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {printf "%-55s%i\n",$i,length($i); i++}}' /boot/grub2/grub.cfg
linux16 7
/vmlinuz-4.18.14-1.el7 22
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46
ro 2
rhgb 4
quiet 5
linux16 7
/vmlinuz-3.10.0-693.el7.x86_64 30
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46
ro 2
rhgb 4
quiet 5
例如:以空格開(kāi)頭0次或多次,后跟linux16的行,以空格為分隔符,只顯示每行中字段的長(cháng)度>=7的字段;
[Allen@centos7 ~]$ sudo awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {printf "%-55s%i\n",$i,length($i)}; i++}}' /boot/grub2/grub.cfg
linux16 7
/vmlinuz-4.18.14-1.el7 22
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46
linux16 7
/vmlinuz-3.10.0-693.el7.x86_64 30
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46
6.4 for
語(yǔ)法:for(expr1;expr2;expr3) statement
特殊用法:for(var in arry) statements ##用于遍歷數組中的元素
實(shí)例
例如:以空格開(kāi)頭0次或多次,后跟linux16的行,以空格為分隔符,顯示每行中各字段的長(cháng)度;
[Allen@centos7 ~]$ sudo awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) printf "%-55s%i\n",$i,length($i)}' /etc/grub2.cfg
linux16 7
/vmlinuz-4.18.14-1.el7 22
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46
ro 2
rhgb 4
quiet 5
linux16 7
/vmlinuz-3.10.0-693.el7.x86_64 30
root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f 46
ro 2
rhgb 4
quiet 5
7. 描述awk函數示例(至少3例)
length([s]):統計s的字符數量;
sub(r,s):將當前行中最左邊第一個(gè)能被r匹配的內容,替換成s;
sub(r,s,t):將t中最左邊第一個(gè)能被r匹配的內容,替換成s;
gsub(r,s):將當前行中能被r匹配的內容,全部替換成s;
gsub(r,s,t ):將t中能被r匹配的內容,全部替換成s;
split(s,a):將s分割,然后分別加入到數組a中(awk命令中沒(méi)有指定FS則使用默認的空格做為分隔符);
split(s,a,fs):使用fs將s分割,然后分別加入到數組a中;
sprintf(format,expr1,expr2,exprn):返回一個(gè)字符串(不打印),這個(gè)字符串按指定的format格式化expr1..exprn
genline:讀取下一行,重新設定NF、NR、FNR;
實(shí)例
實(shí)例1:length函數
[root@centos7 ~]# awk 'BEGIN{superuser="root";print length(superuser)}'
4
實(shí)例2:sub和gsub函數
[root@centos7 ~]# echo "hello World" | awk '{sub("l",1);print $0}'
he1lo World
[root@centos7 ~]# echo "hello World" | awk '{sub("l",1,$1);print $0}'
he1lo World
[root@centos7 ~]# echo "hello World" | awk '{gsub("l",1);print $0}'
he11o Wor1d
[root@centos7 ~]# echo "hello World" | awk '{gsub("l",1,$1);print $0}'
he11o World
實(shí)例3:split函數
數組下標從1開(kāi)始
[root@centos7 ~]# awk -F/ 'BEGIN{i="China/America/Britain";split(i,countrys);for(c=1;c<=3;c++)print countrys[c]}'
China
America
Britain
[root@centos7 ~]# awk 'BEGIN{i="China/America/Britain";split(i,countrys,"/");for(c=1;c<=3;c++)print countrys[c]}'
China
America
Britain
實(shí)例4:sprintf函數
[root@centos7 ~]# awk -F: 'NR>=1&&NR<=5{x=sprintf("%-10s%-5d",$1,$3);print x}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
售前咨詢(xún)
售后咨詢(xún)
備案咨詢(xún)
二維碼
TOP