GNU awk

awk -> gawk – 模式掃描和輸出語言文件, pattern scanning and processing language

基本用法:

gawk [options] 'program' FILE …

program: PATTERN{ACTION ATATEMENTS}

ACTION ATATEMENTS: 動作語句, 可以有多個, 語句之間用分號分隔

print, printf

選項:

-F: 指明輸入時的用到的字段分隔符, 默認為空格

-v, var=value: 自定義變量

1、print

print item1,item2

要點:

(1)輸出時使用逗號分隔符, 默認輸出分隔符為空格

(2)輸出的各item可以是字符串, 也可以是數值; 當前記錄的字段, 變量或者awk的表達式

(3)print中的$#變量替換不能使用""括起來

(4)如省略item, 相當于print $0

2、變量

2.1 內建變量

(1) FS: input fiield seperator, 輸入字段分隔符, 默認為空白字符

OFS: output field seperator, 輸出字段分隔符, 默認為空白字符

示例:

awk -v FS=':' -v OFS=':' '{printf "%20s %s %-20s\n",$1,OFS,$3}' /etc/passwd

或者

awk -F ':' '{print $1}' /etc/passwd

每一個變量前需要一個-v 選項

(2) RS: input record seperator, 輸入換行符, 默認的行分隔符為換行符

ORS: output record seperator, 輸出換行符

示例:

awk -v RS=' ' -v ORS='#' '{print}' /etc/passwd

(3) NF: number of field, 字段數量, 打印每一行的字段的總數量

{print NF} 和{print $NF}的區別

print NF: 打印每行的字段數量

print $NF: 打印每一行的最后一個字段

示例:

awk '/^UUID/{print NF}' /etc/fstab

awk '/^UUID/{print $NF}' /etc/fstab

$NF: 打印每行的最后一個字段

并且NF支持數學運算

示例:

awk '/^UUID/{print $(NF-2)}' /etc/fstab

awk '/^UUID/{print ($NF+1)}' /etc/fstab

(4) NR: number record, 行數, 對行統一執行編號

FNR: file number record, 各文件分別計數, 行數

(5) FILENAME: 當前正在處理的文件名, 處理文件中的一行就會打印一次文件名稱, 有多少行, 打印多少次

示例:

awk '{print FILENAME}' /etc/fstab /etc/issue

(6) ARGC: 內建變量, 命令行中給定的參數個數

ARGV: 內建數組, 保存命令行中所給定的各參數

示例:

awk '{print ARGC}' /etc/fstab /etc/issue

awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue

awk '{print ARGV}' /etc/fstab /etc/issue

awk 'BEGIN{print ARGV[#]}' /etc/fstab

FILENAME: 顯示為文件的內容對應的文件名稱,沒處理一行,就會顯示一次

ARGC: 打印出處理此文件所產生和使用的參數個數, 每處理一行就會顯示一次, 在前邊加上BEGIN后就顯示一次

ARGV: 打印出處理此文件產 生和使用的詳細參數列表, 每處理一行就會打印一次, 前邊增加BEGIN后就只顯示一次, 后邊可以給上對應的數值分別查看

ARGV[#]

2.2 自定義變量

(1)-v var=value

變量名區分字符大小寫

(2) 在program中直接定義

示例:

awk 'BEGIN{test="hello gawk";print test}'

3、printf命令

格式化輸出: printf FORMAT, item1, item2, …

(1)FORMAT必須給出

(2)不會自動換行, 需要顯示給出換行控制符 \n

(3)FORMAT中需要分別為后面的每個item指定一個格式化符號

格式替換符:

%c: 顯示字符的ACSII碼

%d, %i: 顯示十進制整數

%e, %E: 顯示為科學計數法數值顯示

%f: 顯示為浮點數

%g, %G: 以科學計數法或浮點形式顯示

%s: 顯示字符串

%u: 顯示無符號整數

%%: 顯示 % 自身

修飾符:

#[.#]: 第一個#控制顯示的寬度, 第二個控制#控制顯示小數點的精度, 默認為右對齊

%3.1f

-: 左對齊

+: 顯示數值的符號

示例:

awk -F ":" '{printf "Username: %-20s UID: %-5d\n",$1,$3}' /etc/passwd

4、操作符

算數運算操作符

+, -, *, /, ^, %

+x: 把一個字符轉換為數值

字符串操作符: 沒有符號的操作符, 字符串的連接

賦值操作符:

=, +=, -=, *=, /=, %=, ^=, ++, —

比較操作符:

>, >=, <, <=, !=, ==

模式匹配符:

~: 是否匹配

!~: 是否不匹配

邏輯操作符:

&&

||

!

函數調用:

function_name(argue1, argue2, …)

條件表達式:

selector?if-true-expression:if-false-expression

selector?

示例: 

# awk -F ":" '{$3>=1000?usertype="Common User":usertype="Sysadmin or Sysuser";printf "%-10s:%10s\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) 關系表達式, reletional expression: 結果有"真"有"假"; 結果為"真"的才會被處理, 結果為"假"的被過濾掉

真: 結果為非0值, 非空字符串;

示例:

awk -F ":" '$3>=1000{print $1,$3}' /etc/passwd

awk -F ":" '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd

或者用模式匹配:

awk -F ":" '$NF~/bash$/{print $1,$NF}' /etc/passwd

(4) 地址定界, line ranges: 行范圍

startline,endline: /pattern1/,/pattern2/

注意: 不支持直接給出數字的格式定界

可以使用NR進行條件判斷的格式定界

awk -F ":" '(NR>=2&&NR<=10){print $1}' /etc/passwd

(5) BEGIN/END模式

BEGIN{}: 僅在開始處理文本之前, 命令開始之前執行一次的程序

END{}: 僅在文本處理完成之后, 命令結束之前執行一次

示例:

awk -F: 'BEGIN{printf "Username    UID\n"}{printf "%-10s %-10s\n",$1,$3}' /etc/passwd

6、常用的action

(1) expression: 表達式

(2) control statements: 條件控制語句,if, while等

(3) compound statement: 組合語句

(4) input statement: 輸入語句

(5) output statement: 輸出語句

7、控制語句

if(condition) {statement}

if(condition) {statement} else {statement}

while(condition) {statement}

do(statement) while(condition)

for(expr1;expr2;expr3) {statement}

break

continue

delete array[index]: 刪除數組單個元素

delete array: 刪除數組

exit: 退出

{ statement }: 多個語句組合, 中間用 ; 隔開

7.1 if – else

語法: if(condition) statement [else statement]

示例:

(1)~]# awk -F ":" '{if($3>=1000){print $1,$3}}' /etc/passwd

(2)~]# awk -F ":" '{if($3>=1000) {printf "common user: %s\n",$1} else {printf "root or sysuser: %s\n",$1}}' /etc/passwd

(3)~]# awk '{if(NF>5) {print $0}}' /etc/fstab

(4)~]# df -h | awk -F "%" '/^\/dev/{print $1}' | awk '{if($NF>=80) print $1}'

使用場景: 對awk取得的整行或某個字段做條件判斷

7.2 while循環

語法: while(condition) statement

條件為"真", 進入循環; 條件為"假", 退出循環

使用場景: 對一行內的多個字段逐一類似處理時使用; 對數組中的各元素逐一處理時使用

length($var) 求參數的長度

示例:

(1)

~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i, length($i);i++}}' /etc/grub2.cfg

(2)

~]# 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循環

語法: for(expr1;expr2;expr3) statement

for(variable assignment;condition;interation process) {for-body}

~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){if(length($i)>=7){print $i,length($i)}}}' /etc/grub2.cfg

特殊用法:

能夠遍歷數組中的元素;

語法: for(var in array) {for-body}

7.5 switch語句: 多分枝的

語法: switch(expression) {case VALUE1 or /PATTERN/: statement; case VALUE2 or /PATTERN/: statement;… default: statement}

7.6 break和continue

break[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"格式進行

示例:

awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}' 

awk '!array[$0]++' FILE  過濾掉文件中的重復的行

若要遍歷數組中的每個元素, 要使用for循環

for(var in array) {for-body}

示例:

awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print i,weekdays[i]}}'

存放方式為棧區存放, 為先進后出的方式

注意: var會遍歷array的每個索引

示例:

netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) print i,state[i]}'

報告生成器, 來生成報告

練習: 

(1)統計/etc/fstab文件中每個單詞出現的次數

awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(j in count){print j,count[j]}}' /etc/fstab

(2)統計/etc/fstab文件中每個系統類型出現的次數

awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab

9、函數

9.1 內置函數

數值處理

rand(): 返回0和1之間的一個隨機數

示例:

awk 'BEGIN{srand();for(i=1;i<=10;i++)print int(rand()*100)}'

int: 對數值取整處理

字符串處理:

length([s]): 返回指定字符串的長度

sub(r,s,[t]): 以r所表示的模式, 來查找t所表示的字符串中的匹配的內容, 并將其第一次出現的內容替換為s表示的內容

示例:

awk 'sub(/:/,"-",$1)' /etc/passwd

gsub(r,s,[t]): 以r所表示的模式, 來查找t所表示的字符串中的匹配的內容, 并將所有出現的內容替換為s所表示的內容

split(s,a[,r]): 以r為分隔符, 去切割字符串s, 并將切割后的結果保存至a所表示的數組中

示例: 顯示鏈接的TCP地址出現的次數

~]# netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in count) {print i,count[i]}}'

9.2 自定義函數

格式:

function name(parameter,parameter,…){

statements

return expression

}

示例:

~]# cat fun.awk

function max(v1,v2){

v1>v2?var=v1:var=v2

return var

}

END{a3;b=2;print max(a,b);}

~]# awk -f fun.awk testfile

原創文章,作者:black_fish,如若轉載,請注明出處:http://www.www58058.com/47868

(0)
black_fishblack_fish
上一篇 2016-09-22 10:04
下一篇 2016-09-22 10:04

相關推薦

  • Linux 文件系統權限

    一、簡述權限  文件系統的權限管理機制的建立,約束了用戶對數據的操作。 1、對系統安全而言  管理員的操作權限非常大,足以破壞系統,權限機制將管理員與普通用戶之間區分開,防止系統被隨意破壞。 2、對用戶而言  Linux是一個多用戶的操作系統,不同用戶間為了防止其他人破壞數據或訪問數據,文件系統的權限管理是非常必要的。 二、文件…

    Linux干貨 2016-08-04
  • Linux之計劃任務

    Linux 之計劃任務    任務計劃Linux任務計劃、周期性任務執行未來的某時間點執行一次任務:atbatch:系統自行選擇空閑時間去執行此處指定的任務周期性運行某任務:cron   at任務at命令:at [option] TIME常用選項:-V 顯示版本信息:-l: 列出指定隊列中等待運行的作業;相當于atq-d: 刪除…

    Linux干貨 2016-09-11
  • 系統管理中的三大利刃(htop glances dstat)

    工欲善事情,必先利其器,生產環境中的服務器在處理請求并生成回應數據的時間主要消耗在服務器端,包括了眾多的環節,如何全面了解我們linux服務器的CPU使用率、使用時間、內存占用比例、磁盤IO數據、網絡相關數據等等眾多指標,保證我們的linux服務器順利完成每一個請求,怎能沒有幾個趁手的利刃,而今天就讓我們見識一下系統管理中三大利刃。 相傳一把三尺長的軟劍,叫…

    Linux干貨 2015-11-18
  • mysql基礎概念筆記 part1

    mysql基礎概念筆記     part1#wmd-preview h1 { color: #0077bb; /* 將標題改為藍色 */} mysql基礎概念筆記     part1 mysql 基礎概念 基礎原理,邏輯架構,事務,并發控制,讀寫鎖 1、前言     作為一個運維…

    Linux干貨 2016-09-19
  • day5作業

    軟硬鏈接區別: 1 硬鏈接會增加連接數,而軟鏈接不會。 2 硬鏈接始終表示的只是一個文件,只是名字不同而已,而軟鏈接本身就是一個獨立的文件,文件內容為指向的文件的路徑。 3 命令格式不同。 硬鏈接: ln filename linkname 軟鏈接: ln -s filename&nbsp…

    系統運維 2016-08-08

評論列表(1條)

  • 馬哥教育
    馬哥教育 2016-09-23 13:08

    awk是一個很方便的文本格式化工具,這也是以后面試題必會遇到的面試題,希望下來多加練習,熟練掌握,

欧美性久久久久