文本处理三剑客awk的使用
1、awk
awk是一種編程語言,用于在Linux/unix下對文本和數(shù)據(jù)進(jìn)行處理。數(shù)據(jù)可以來自標(biāo)準(zhǔn)輸入、一個(gè)或多個(gè)文件,或其他命令的輸出。awk支持函數(shù)、正則表達(dá)式、數(shù)組等先進(jìn)功能。
awk處理文本和數(shù)據(jù)的方式是先逐行掃描文件,從第一到最后一行,尋找匹配的特定模式的行,并在這些找出的行上進(jìn)行分段操作。如果沒有指定處理動(dòng)作,則把匹配到的行顯示到標(biāo)準(zhǔn)輸出(屏幕),如果沒有指定模式,則所有被操作所指定的行都被處理,它可以在命令行中使用,更多是作為腳本中一部分來使用。
2、awk中的變量
(1)awk的內(nèi)置變量
FS(input field seperator):輸入時(shí)字段分隔符,默認(rèn)為空白字符;作用同-F參數(shù)
OFS(output field seperator):輸出時(shí)字段分隔符,默認(rèn)為空白字符;
RS(input record seperator):輸入時(shí)的換行符;
ORS(output record seperator):輸出時(shí)的換行符;
NF(number of field):字段數(shù)量
NR(number of record): 行數(shù);多個(gè)文件和當(dāng)一個(gè)文件對待
FNR:各文件分別計(jì)數(shù),行數(shù);
FILENAME:當(dāng)前文件名;
ARGC:命令行參數(shù)的個(gè)數(shù);
ARGV:數(shù)組,保存的是命令行所給定的各參數(shù);
#?FS的使用,作用同-F [root@node02?~]#?awk?-v?FS=':'?'{print?$1}'?/etc/passwd|head?-2 root bin [root@node02?~]#?awk?-F:?'{print?$1}'?/etc/passwd|head?-2 root bin #?指定分隔符為\t,換行符為# [root@node02?~]#?head?-2?/etc/passwd|awk?-F:?-v?OFS="\t"?-v?ORS='#'?'{print?$1,$3}' root???????0#bin????1 #?NF為輸出行字段的數(shù)量,$NF為輸出最后一個(gè)字段 [root@node02?~]#?awk?-F:?'{print?NF}'?/etc/passwd|head?-2 7 7 [root@node02?~]#?awk?-F:?'{print?$NF}'?/etc/passwd|head?-2 /bin/bash /sbin/nologin #?輸出的每一行都會(huì)用該文件名來代替 [root@node02?~]#?awk?'{print?FILENAME}'?/etc/fstab??/etc/passwd /etc/fstab .?.?.?.?.?. /etc/passwd #?每一行都會(huì)顯示參數(shù)的個(gè)數(shù) [root@node02?~]#?awk?'{print?ARGC}'?/etc/fstab??/etc/passwd 3 3 .?.?.?.?.?. #?只顯示一次參數(shù)的個(gè)數(shù) [root@node02?~]#?awk?'BEGIN{print?ARGC}'?/etc/fstab??/etc/passwd 3 #?顯示指定的參數(shù),第0個(gè)參數(shù)為awk自身 [root@node02?~]#?awk?'BEGIN{print?ARGV[0]}'?/etc/fstab??/etc/passwd awk(2)awk的內(nèi)置變量
Awk中自定義變量時(shí)通過-v選項(xiàng)自定義變量,同時(shí)也可在在program中直接定定義。
[root@node02?~]#?awk?-v?test="hello?awk"?'BEGIN{print?test}'?/etc/fstab hello?awk [root@node02?~]#?awk?'BEGIN{test="awk";print?test}' awk3、awk中printf輸出命令的使用
Awk中printf也為輸出,相對于print輸出,print不會(huì)自動(dòng)換行,需要顯式給出換行控制符”\n”, FORMAT必須給出, FORMAT中需要分別為后面的每個(gè)item指定一個(gè)格式化符號(hào)。
(1)使用printf輸出時(shí)的格式符
%c: 顯示字符的ASCII碼;
%d, %i: 顯示十進(jìn)制整數(shù);
%e, %E: 科學(xué)計(jì)數(shù)法數(shù)值顯示;
%f:顯示為浮點(diǎn)數(shù);
%g, %G:以科學(xué)計(jì)數(shù)法或浮點(diǎn)形式顯示數(shù)值;
%s:顯示字符串;
%u:無符號(hào)整數(shù);
%%: 顯示%自身;
(2)使用printf輸出時(shí)的裝飾符
#[.#]:第一個(gè)數(shù)字控制顯示的寬度;第二個(gè)#表示小數(shù)點(diǎn)后的精度;
-: 左對齊
+:顯示數(shù)值的符號(hào)
#?默認(rèn)輸出是不換行的 [root@node02?~]#?awk?-F:?'{printf?"%s",$3}'?/etc/passwd 01234567811121499192819997489998322965534997996995994993 #?使用\n換行輸出 [root@node02?~]#?awk?-F:?'{printf?"username:?%s?\t?uid:%d\n",$1,$3}'?/etc/passwd|head?-2 username:?root???????uid:0 username:?bin????????uid:1 #?輸出時(shí)左對齊并且用戶名字段的長度為15個(gè)字符 [root@node02?~]#?awk?-F:?'{printf?"username:?%-15s?\t?uid:%d\n",$1,$3}'?/etc/passwd|?head?-3 username:?root?????????????????uid:0 username:?bin??????????????????uid:14、awk中算術(shù)運(yùn)算符
運(yùn)算符 | 描述 |
= += -+ *= /= %= ^= **= | 賦值語句 |
||? ? && | 邏輯與、邏輯或 |
~? ? !~ | 匹配則正表達(dá)式和不匹配正則表達(dá)式 |
< <= > >= != == | 關(guān)系運(yùn)算符 |
+ - * / & ** ++ -- | 算術(shù)運(yùn)算符 |
$ | 字段引用 |
空格 | 字符串連接符 |
?: | 三目運(yùn)算符 |
ln | 數(shù)組中是否存在某鍵值 |
5、awk中的模式匹配
(1) empty:空模式,匹配每一行;
(2)/regular expression/:僅處理能夠被此處的模式匹配到的行;
(3)關(guān)系表達(dá)式;結(jié)果有“真”有“假”;結(jié)果為“真”才會(huì)被處理;真是結(jié)果為非0值,非空字符串;
(4)行范圍的匹配,不支持直接給出數(shù)字的格式
(5)BEGIN/END模式, BEGIN{}僅在開始處理文件中的文本之前執(zhí)行一次;END{}僅在文本處理完成之后執(zhí)行一次;
#?輸出fstab文件中以UUID或/dev開頭的行 [root@node02?~]#?awk?'/^UUID|^\/dev/{print?$1}'?/etc/fstab /dev/mapper/centos-root UUID=8dcf68e6-ba4c-4aaa-abd9-d008f1ecbe51 #?輸出uid大于1000的用戶 [root@node02?~]#?awk?-F:?'$3>=1000{print?$1,$3}'?/etc/passwd nfsnobody?65534 #?輸出bash為/bin/bash的用戶 [root@node02?~]#?awk?-F:?'$NF=="/bin/bash"{print?$1,$3,$NF}'?/etc/passwd root?0?/bin/bash #?行范圍的匹配 [root@node02?~]#?awk?-F:?'(NR>=2&&NR<=4){print?$1}'?/etc/passwd bin daemon adm #?BEGIN/END模式輸出 [root@node02?~]#?awk?-F:?'BEGIN{print?"username\t\tuid\n------------------"}{printf?"%s\t\t\t%d\n",$1,$3}END{print?"=================================\nend"}'?/etc/passwd|head?-5 username???????????uid ------------------ root????????????????????????0 bin?????????????????????????1 daemon??????????????????????26、awk中使用控制語句
?????? awk中的條件語句是從C語言中借鑒過來的,可控制程序的流程.
(1)if-else語句
語句格式:if(condition) statement [else statement]
#?輸出bash為“/bin/bash”的用戶 [root@node02?~]#?awk?-F:?'{if($NF=="/bin/bash")?print?$1}'?/etc/passwd root #?判斷用戶類型 [root@node02?~]#?awk?-F:?'{if($3>=1000)?{printf?"Commonuser:?%s\n",$1}?else?if($3==0){printf?"admin-user:?%s\n",$1}??else?{printf?"Sysuser:?%s\n",$1}}'?/etc/passwd admin-user:?root Sysuser:?bin #?判斷一行的字?jǐn)?shù)大于5個(gè)時(shí)輸出整行 [root@node02?~]#?awk?'{if(NF>5)?print?$0}'?/etc/fstab #?Created?by?anaconda?on?Fri?Jan??4?01:49:11?2019 #?Accessible?filesystems,?by?reference,?are?maintained?under #?列出磁盤使用率大于等于10%的分區(qū) [root@node02?~]#?df?-h?|?awk?-F[%]?'/^\/dev/{print?$1}'?|?awk?'{if($NF>=10)?print?$1}' /dev/sda1(2)while語句
?????? While語句用于當(dāng)條件成立時(shí)進(jìn)入循環(huán),當(dāng)條件不成立時(shí)推出循環(huán),常用于對一行內(nèi)的多個(gè)字段逐一類似處理時(shí)或數(shù)組中的各元素逐一處理。
#?統(tǒng)計(jì)liunx所在行的每個(gè)字段的長度 [root@node02?~]#?awk?'/^[[:space:]]*linux16/{i=1;while(i<=NF)?{print?$i,length($i);?i++}}'?/etc/grub2.cfg linux16?7 /vmlinuz-3.10.0-862.el7.x86_64?30 root=/dev/mapper/centos-root?28 #?統(tǒng)計(jì)liunx所在行的每個(gè)字段的長度并輸出長度大于7的字段及長度 [root@node02?~]#?awk?'/^[[:space:]]*linux16/{i=1;while(i<=NF)?{if(length($i)>=7)?{print?$i,length($i)};?i++}}'?/etc/grub2.cfg linux16?7 /vmlinuz-3.10.0-862.el7.x86_64?30 root=/dev/mapper/centos-root?28(3)for語句
#?上面的案例使用for語句實(shí)現(xiàn)為 [root@node02?~]#?awk?'/^[[:space:]]*linux16/{for(i=1;i<=NF;i++)?if(length($i)>=7){print?$i,length($i)}}'?/etc/grub2.cfg linux16?7 /vmlinuz-3.10.0-862.el7.x86_64?30 root=/dev/mapper/centos-root?28(4)其他控制語句
?????? 除了上述常用的控制語句外,其他的控制語句還有do-while循環(huán),switch語句,break和continue,next(前結(jié)束對本行的處理而直接進(jìn)入下一行)。
7、awk中的數(shù)組
?????? awk中的數(shù)組的下標(biāo)可以是數(shù)字和字母,稱為關(guān)聯(lián)數(shù)組;下標(biāo)可使用任意字符串;字符串要使用雙引號(hào);如果某數(shù)組元素事先不存在,在引用時(shí),awk會(huì)自動(dòng)創(chuàng)建此元素,并將其值初始化為“空串”。
#?定義一個(gè)數(shù)組并遍歷輸出數(shù)組中的每個(gè)元素 [root@node02?~]#?awk?'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i?in?weekdays)?{print?weekdays[i]}}' Tuesday Monday #?統(tǒng)計(jì)每種TCP狀態(tài)的數(shù)量 [root@node02?~]#?netstat?-tan?|?awk?'/^tcp\>/{state[$NF]++}END{for(i?in?state)?{?print?i,state[i]}}' LISTEN?19 ESTABLISHED?24 TIME_WAIT?3 #?統(tǒng)計(jì)fstab中每種類型的文件系統(tǒng)出現(xiàn)的次數(shù) [root@node02?~]#?awk?'/^UUID|^\/dev/{fs[$3]++}END{for(i?in?fs)?{print?i,fs[i]}}'?/etc/fstab swap?1 xfs?2 #?統(tǒng)計(jì)fstab中每個(gè)字段出現(xiàn)的次數(shù) [root@node02?~]#??awk?'{for(i=1;i<=NF;i++){count[$i]++}}END{for(i?in?count)?{print?i,count[i]}}'?/etc/fstab swap?2 fstab(5),?18、awk中的函數(shù)
?????? awk中常用的內(nèi)置函數(shù)有:
????????????? rand():返回0和1之間一個(gè)隨機(jī)數(shù);
????????????? length([s]):返回指定字符串的長度;
?sub(r,s,[t]):以r表示的模式來查找t所表示的字符中的匹配的內(nèi)容,并將其第一次出現(xiàn)替換為s所表示的內(nèi)容;
?gsub(r,s,[t]):以r表示的模式來查找t所表示的字符中的匹配的內(nèi)容,并將其所有出現(xiàn)均替換為s所表示的內(nèi)容;
?split(s,a[,r]):以r為分隔符切割字符s,并將切割后的結(jié)果保存至a所表示的數(shù)組中;
#?統(tǒng)計(jì)機(jī)同外部每個(gè)ip建立tcp連接的數(shù)量 [root@node02?~]#?netstat?-tan?|?awk?'/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for?(i?in?count)?{print?i,count[i]}}' 192.168.17.195?1 192.168.17.196?3 #?將匹配到的第一個(gè)root替換為admin [root@node02?~]#?awk?-F:?'{?sub(/root/,?"admin");?print?}'?/etc/passwd admin:x:0:0:root:/root:/bin/bash轉(zhuǎn)載于:https://blog.51cto.com/dayi123/2366999
總結(jié)
以上是生活随笔為你收集整理的文本处理三剑客awk的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 以太坊智能合约 solidity 的常用
- 下一篇: 比特币的缺陷以及改进