awk學習隨常記錄
回顧:字符串處理
數組:
數組 : declare -a
index: 0-
關聯數組 : declare -A
編程:數據結構和算法
字符串處理:
切片、查找替換、查找刪除、變量賦值
GUN awk:
文本處理三工具: grep ,sed ,awk
grep:grep、egrep 、fgrep:文本過濾工具:pattern
sed:行編輯器
模式空間、保持空間
awk:報告生成器,格式化文本輸出;
AWK: aho,weinberger, kernigha 命名就用三個人名字的首字母
awk主要是在unix上使用。linux用的為GUN版的awk簡稱gawk
基本用法
awk [options] ‘program‘ FILE...
program : PATTERN{ACTION STATEMENT}
語句之間用分號分隔
print,printf
選項:
-F 字段分隔符,指明輸入時的字段分隔符
-v 自定義變量 var=value
以文件中的行為單位進行讀取,以-F指定的分隔符為標識來分隔讀取的內容
整個行為$0 第一片為$1
awk的循環功能不是在行間循環的,awk自身就能遍歷文件
tail -3 /etc/fstable|awk ‘{print $2,$4}‘
1、print item1,item2
(1)逗號為分隔符;
(2) 輸出的各item可以是字符串,也可以是數值,也可以是awk自己的變量或表達式。
(3) 如省略item,相當於print $0
2、變量
2.1內建變量
FS:input field seperator,默認為空白字符
awk ‘{print $1}‘ /etc/passwd
awk -v FS=":" ‘{print $1}‘ /etc/passwd
等於
awk -F
awk -v FS=‘:‘ ‘{print $1}‘ /etc/passwd
OFS:output field seperator ,默認為空白字符 輸出字段默認分隔符
RS:input record seperator,輸入時的換行符
OFS:outpu record seperator,輸出時的換行符
NF: number of field 每一行的字段數量
NR:number of record 行數:顯示一個文件一個有多少行
FNR:file number of record 每一個文件分別計行數
FILENAME:文件名 當前正在正理的文件的文件名
ARGC:命令行中參數的個數
ARGV:保存命令行中所給定的各參數 是一個數組,調用方式為 ARGV[0] ARGV[1]
自定義變量
-v var=value
(1)變量名區分字符大小寫
(2)在program中直接定義
3、printf命令
格式化輸出:printf FORMAT,item1,item2,item3...
(1)FORMAT是必須給出
(2)printf不行自動換行,需要顯式給出換行符,\n
(3)FORMAT中需要分別為後面的每個item指定一個格式化符號:
格式符:
%c:顯示字符的ASCII碼
%d,%i 顯示十進制整數
%e %E 科學計數法數值顯示
%g %G 以科學計數或浮點形式顯示數值
%u 無符號整數
%% 顯示%自身:
%s 顯示字符串
awk -F : ‘{printf "Username:%s\n",$1 }‘ /etc/passwd
awk -F : ‘{printf "%s\n",$1 }‘ /etc/passwd
awk -F : ‘{printf "%s",$1 "\n"}‘ /etc/passwd
awk -F : ‘{printf "Username: %s,UDI %d \n",$1,$3}‘ /etc/passwd
修飾符:
#[.#]:第一個數字用來控制顯示的寬度,第二個數字用來控制小數點後的精度
%3.1f
awk -F : ‘{printf "Username: %15s,UDI %d \n",$1,$3}‘ /etc/passwd
- -號表示左對齊
awk -F : ‘{printf "Username: %-15s,UDI %d \n",$1,$3}‘ /etc/passwd
+:顯示數值的符號
4、操作符
算術運算操作符
x+y,x-y,x*y,x/y,x%y
-x 取反
+x 把字符轉換為數值
字符串操作符:沒有符號的操作符,字符串連接
賦值操作符
=,+=,-=,*=,/=,%=,^=,++,--
比較操作符
>,>=,<.<=,!=,==
模式匹配符:
~:左側字符串是否表示匹配右側字符串
!~表示不匹配
邏輯操作符:
&&
||
!
函數調用:
function_name(arguments1,arguments2...)
條件表達式:
selector ? if-true-expression: if-false-expression
awk -F: ‘{$3>=1000?usertype="Commen User":usertype="Systemadmin or Sysuser";printf"%15s:%-s\n",$1,usertype}‘ /etc/passwd
5、PATTERN
實現地址定界的功能
(1)empty:空模式,匹配每一行
(2)/regular expression/: 正則表達式
awk ‘!/^UUID/{print $1}‘ /etc/fstab
awk ‘!/^UUID/{print $1}‘ /etc/fstab
(3)關系表達式:relational expression:關系表達式:關系表達式:結果有“真”有"假“結果非0值為真。
awk -F : ‘$NF=="/bin/bash"{print $1,$NF}‘ /etc/passwd
awk -F : ‘$NF~/bash$/{print $1,$NF}‘ /etc/passwd
(4)lin ranges:行範圍 地址定界
awk -F : ‘/^root/,/^tcpdump/{print $1}‘ /etc/passwd
awk -F : ‘/^root/,/^tcpdump/{print $1}‘ /etc/passwd
awk -F : ‘(NR>=2&&NR<=10){print $1}‘ /etc/passwd
不支持直接給出數字的格式,可以用變量來限制行範圍
(5)BEGIN/END模式
BEGIN{}:僅在開始處理文件中的文本之前執行一次;
END{}:僅在文本處理完成之後執行一次;
awk -F: ‘BEGIN{print " username uid \n-----------------------------"} {print $1,$3} END{print"=========== \n end"}‘ /etc/passwd
6常用的action
(1)Expressions
(2) Control statements: if while 等
(3)Compound statements:組合語句
(4)input statements
(5) output statements
7控制語句
(1)if if(conditons){statments}
if(conditions){statments}else{statments}
(2)while(condition){statments}
(3)do statments}
(4) for(expr1;expr2;expr3){statements}
break
continue
delete array [index]
delete array
exit
{statements} 多個語句語句是需要用花括號括起來的
7.1 if-else{statments}
語法 if(condition)statement[else statement]
某個用戶的id號大於1000
awk -F: ‘{if($3>=1000){ printf"commen user:%s\n ",$1} else {printf "root or Sysuser %s \n ",$1} }‘ /etc/passwd
使用場景:對awk取得的整行或某個字段做條件判斷:
awk -F: ‘{if($NF=="/bin/bash") print $1}‘ /etc/passwd
awk ‘{if(NF>5) print $0}‘ /etc/fstab
7.2 while 循環
語法:while(condition) statement
條件為”真“,進入循環;條件為假,退出循環;
使用場景 :對一行內的多個字段 逐一類似處理時使用:對數組中的各元素逐一處理時使用
顯示這個字段
lenth()
awk ‘/^[[:space:]]*linux16/{print}‘ /etc/grub2.cfg
awk ‘/^[[:space:]]*linux16/{i=1;while(i<NF){print $i,length($i);i++}}‘ /etc/grub2.cfg
awk ‘/^[[:space:]]*linux16/{i=1;while(i<NF){if(length($i)>=7){print $i,length($i)};i++}}‘ /etc/grub2.cfg
7.3 do-while循環
語法
do statement while(condition)
意義:至少執行一次循環體
7.4 for(expr1;expr2;expr3) statement
for(variable assignment;condition;internation process){for-body}
awk ‘/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}‘ /etc/grub2.cfg
特殊用法
能夠遍歷數組中的元素
for(var in array) {for-body}
7.5 swithc 語句
語法 switch(expression){case VALUE1 or /REGEXP/ :statement;case VALUE2 or/REGEXP2/:statement....;default statement}
7.6 break和continue
break[n] 退出n輪循環
continue
7.7 next 提前結束對本行的處理,而直接進入下一行:
awk -F: ‘{if($3%2!=0) next; print $1,$3}‘ /etc/passwd
8、array 數組 -連續的內存空間,分為兩類 一、數字索引的數組 二、關聯數組
array[index-expression]
index-expression:
(1)可以使用任意字符串 字符串要使用雙引號
(2)如果某數組元素事先不存在,在引用時awk會自動創建此元素,並將其值初始化為空串
若要判斷數組中是否存在某元素,要使用”index in array"格式進行
weekdays[mon]=monday
awk ‘BEGIN{weekdays[mon]="monday";weekdays[tue]="tuesday";print weekdays[mon]}‘
awk ‘BEGIN{weekdays["mo"n]="monday";weekdays["tue"]="tuesday";print weekdays["mo"n]}‘
awk ‘BEGIN{weekdays["mo"n]="monday";weekdays["tue"]="tuesday";print weekdays["mo"n]}‘
awk ‘BEGIN{weekdays["mo"n]="monday";weekdays["tue"]="tuesday";print weekdays["tue"]}‘
awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays) print weekdays[i]}‘
若要遍歷數組中的每個元素,要使用for循環:
for(var in array) {for-body}
註意:var會遍歷array的每個索引
awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays) print weekdays[i]}‘
netstat -tan
state["LISTEN"]++
state["ESTABLISHED"]++
netstat -tan|awk ‘/^tcp\>/{state[$NF]++}END{for(i in state ){print i ,state[i]}}‘
ss -tan
awk ‘{ip[$1]++}END{for( i in ip){print i,ip[i]}}‘ /var/log/httpd/access_log
統計ip訪問網站的次數
練習題 統計/etc/fstab中每個單詞出現的次數
awk ‘!/^#/{fs[$3]++}END{for(i in fs){print i,fs[i]}}‘ /etc/fstab
awk ‘/^UUDI/{fs[$3]++}END{for(i in fs){print i,fs[i]}}‘ /etc/fstab
統計/etc/fstab中每個文件類型出在的次數
awk ‘{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}‘ /etc/fstab
9內置函數
9.1內置函數
數值處理
rand():返回一個0和1之間的小數 只有第一次取的是隨機的,後面的數字都是同一個
sin()
cos()
字符串處理的 length() 返回指定字符串的長度
sub(r,s,[t]);以r表示的模式查找t所表示的字符的字符中匹配的內容,並將第一次出現替換為s所表示的內容:
gsub()表示全局替換以r表示的模式查找t所表示的字符的字符中匹配的內容,並將所有出下替換為s所表示的內容
split(s,a[,r])以r為分隔符,切割字符串s,並將切割後的結果保存至a所表示的數組中;
推薦看 sed和awk
awk學習隨常記錄