文本处理三剑客awk的使用
1、awk
awk是一種編程語言,用于在Linux/unix下對文本和數據進行處理。數據可以來自標準輸入、一個或多個文件,或其他命令的輸出。awk支持函數、正則表達式、數組等先進功能。
awk處理文本和數據的方式是先逐行掃描文件,從第一到最后一行,尋找匹配的特定模式的行,并在這些找出的行上進行分段操作。如果沒有指定處理動作,則把匹配到的行顯示到標準輸出(屏幕),如果沒有指定模式,則所有被操作所指定的行都被處理,它可以在命令行中使用,更多是作為腳本中一部分來使用。
2、awk中的變量
(1)awk的內置變量
FS(input field seperator):輸入時字段分隔符,默認為空白字符;作用同-F參數
OFS(output field seperator):輸出時字段分隔符,默認為空白字符;
RS(input record seperator):輸入時的換行符;
ORS(output record seperator):輸出時的換行符;
NF(number of field):字段數量
NR(number of record): 行數;多個文件和當一個文件對待
FNR:各文件分別計數,行數;
FILENAME:當前文件名;
ARGC:命令行參數的個數;
ARGV:數組,保存的是命令行所給定的各參數;
#?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為輸出行字段的數量,$NF為輸出最后一個字段 [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 #?輸出的每一行都會用該文件名來代替 [root@node02?~]#?awk?'{print?FILENAME}'?/etc/fstab??/etc/passwd /etc/fstab .?.?.?.?.?. /etc/passwd #?每一行都會顯示參數的個數 [root@node02?~]#?awk?'{print?ARGC}'?/etc/fstab??/etc/passwd 3 3 .?.?.?.?.?. #?只顯示一次參數的個數 [root@node02?~]#?awk?'BEGIN{print?ARGC}'?/etc/fstab??/etc/passwd 3 #?顯示指定的參數,第0個參數為awk自身 [root@node02?~]#?awk?'BEGIN{print?ARGV[0]}'?/etc/fstab??/etc/passwd awk(2)awk的內置變量
Awk中自定義變量時通過-v選項自定義變量,同時也可在在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不會自動換行,需要顯式給出換行控制符”\n”, FORMAT必須給出, FORMAT中需要分別為后面的每個item指定一個格式化符號。
(1)使用printf輸出時的格式符
%c: 顯示字符的ASCII碼;
%d, %i: 顯示十進制整數;
%e, %E: 科學計數法數值顯示;
%f:顯示為浮點數;
%g, %G:以科學計數法或浮點形式顯示數值;
%s:顯示字符串;
%u:無符號整數;
%%: 顯示%自身;
(2)使用printf輸出時的裝飾符
#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點后的精度;
-: 左對齊
+:顯示數值的符號
#?默認輸出是不換行的 [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 #?輸出時左對齊并且用戶名字段的長度為15個字符 [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中算術運算符
運算符 | 描述 |
= += -+ *= /= %= ^= **= | 賦值語句 |
||? ? && | 邏輯與、邏輯或 |
~? ? !~ | 匹配則正表達式和不匹配正則表達式 |
< <= > >= != == | 關系運算符 |
+ - * / & ** ++ -- | 算術運算符 |
$ | 字段引用 |
空格 | 字符串連接符 |
?: | 三目運算符 |
ln | 數組中是否存在某鍵值 |
5、awk中的模式匹配
(1) empty:空模式,匹配每一行;
(2)/regular expression/:僅處理能夠被此處的模式匹配到的行;
(3)關系表達式;結果有“真”有“假”;結果為“真”才會被處理;真是結果為非0值,非空字符串;
(4)行范圍的匹配,不支持直接給出數字的格式
(5)BEGIN/END模式, BEGIN{}僅在開始處理文件中的文本之前執行一次;END{}僅在文本處理完成之后執行一次;
#?輸出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 #?判斷一行的字數大于5個時輸出整行 [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%的分區 [root@node02?~]#?df?-h?|?awk?-F[%]?'/^\/dev/{print?$1}'?|?awk?'{if($NF>=10)?print?$1}' /dev/sda1(2)while語句
?????? While語句用于當條件成立時進入循環,當條件不成立時推出循環,常用于對一行內的多個字段逐一類似處理時或數組中的各元素逐一處理。
#?統計liunx所在行的每個字段的長度 [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 #?統計liunx所在行的每個字段的長度并輸出長度大于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語句實現為 [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循環,switch語句,break和continue,next(前結束對本行的處理而直接進入下一行)。
7、awk中的數組
?????? awk中的數組的下標可以是數字和字母,稱為關聯數組;下標可使用任意字符串;字符串要使用雙引號;如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其值初始化為“空串”。
#?定義一個數組并遍歷輸出數組中的每個元素 [root@node02?~]#?awk?'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i?in?weekdays)?{print?weekdays[i]}}' Tuesday Monday #?統計每種TCP狀態的數量 [root@node02?~]#?netstat?-tan?|?awk?'/^tcp\>/{state[$NF]++}END{for(i?in?state)?{?print?i,state[i]}}' LISTEN?19 ESTABLISHED?24 TIME_WAIT?3 #?統計fstab中每種類型的文件系統出現的次數 [root@node02?~]#?awk?'/^UUID|^\/dev/{fs[$3]++}END{for(i?in?fs)?{print?i,fs[i]}}'?/etc/fstab swap?1 xfs?2 #?統計fstab中每個字段出現的次數 [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中的函數
?????? awk中常用的內置函數有:
????????????? rand():返回0和1之間一個隨機數;
????????????? length([s]):返回指定字符串的長度;
?sub(r,s,[t]):以r表示的模式來查找t所表示的字符中的匹配的內容,并將其第一次出現替換為s所表示的內容;
?gsub(r,s,[t]):以r表示的模式來查找t所表示的字符中的匹配的內容,并將其所有出現均替換為s所表示的內容;
?split(s,a[,r]):以r為分隔符切割字符s,并將切割后的結果保存至a所表示的數組中;
#?統計機同外部每個ip建立tcp連接的數量 [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 #?將匹配到的第一個root替換為admin [root@node02?~]#?awk?-F:?'{?sub(/root/,?"admin");?print?}'?/etc/passwd admin:x:0:0:root:/root:/bin/bash轉載于:https://blog.51cto.com/dayi123/2366999
總結
以上是生活随笔為你收集整理的文本处理三剑客awk的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 以太坊智能合约 solidity 的常用
- 下一篇: 比特币的缺陷以及改进