1. 程式人生 > >awk學習隨常記錄

awk學習隨常記錄

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學習隨常記錄