linux命令終極學習-awk

收藏學習,感謝分享!
一.awk功能特點
awk是一個非常重要的命令或者認爲是一種語言。因爲他可以做數學運算,流程控制語句,流控制,還有樣式裝入的功能。反正是非常強大。awk是三位創建者編寫的。把awk定義爲:樣式掃描處理語言。
awk吸收了C語言很多的特點,所以與C語言有點類擬。

二.awk的調用方式
awk提供了適應不同需要的多種方案,它們是:
1.awk命令行
像普通的unix命令一樣使用awk,當然可以在你的命令行中使用awk設計語言。而且還可以在shell腳本中引用awk命令或awk程序腳本。
2.使用-f選項調用awk程序。
awk可以將一段awk程序腳本寫入到一個文本文件,然後使用-f選項來指定執行這個awk語言腳本。
3.利用命令解釋器調用awk程序
利用unix支持的命令解釋功能。可以將一段awk程序寫入到文本文件,然後在它的第一行加上:

    #!/bin/awk -f

並chmod u+x權限。這樣以後,你就可以用以下命令格式來調用了。

   $awk 腳本文件名  待處理的文件

三.awk語法
1.與其他的unix命令一樣,它的語法如下:

    awk [ -F re] [parameter...] ['prog'] [-f progfile][in_file...] 

參數說明:
-F re,指定某字符爲分隔符
parameter:該參數幫助不同的變量賦值
'prog': awk的程序語句段。這個語句段必須用'與'括起來。以防被shell給解釋掉了。它的標準形式如下:
'pattern {action}'
其中pattern參數可以是grep正則表達式中的任何一個,它可以使用語法/re/再加上一些樣式匹配技巧構成,也可以使用","分開兩樣式以選擇某個範圍。。 action參數總是被大括號包圍,它由一系統awk語句組成,各語句之間用";"分隔。awk解釋它們,並在pattern給定的樣式匹配的記錄上執行 其操作。與shell類似,你也可以使用“#”作爲註釋符,它使“#”到行尾的內容成爲註釋,在解釋執行時,它們將被忽略。你可以省略pattern和 action之一,但不能兩者同時省略,當省略pattern時沒有樣式匹配,表示對所有行(記錄)均執行操作,省略action時執行缺省的操作——在 標準輸出上顯示。

-f profile:允許awk調用並執行progfile指定程序文件。progfile是一個文本文件,他必須符合awk的語法(注意不是shell文件)。

in_file :awk的輸入文件,可以有多個。注意:awk不會修改輸入文件。如果沒有指定輸入文件,那麼默認爲標準輸入(屏幕)

四. awk的記錄,字段與內置變量
 1. 記錄與字段
在 awk中,缺省的情況下總是將文本文件中的一行視爲一個記錄,而將一行中的某一部分作爲記錄中的一個字段。爲了操作這些不同的字段,awk借用shell 的方法,用$1,$2,$3...這樣的方式來順序地表示行(記錄)中的不同字段。特殊地,awk用$0表示整個行(記錄)。不同的字段之間是用稱作分隔 符的字符分隔開的。系統默認的分隔符是空格。awk允許在命令行中用-F re的形式來改變這個分隔符。事實上,awk用一個內置的變量FS來記憶這個分隔符

2. 內置變量
  awk中有好幾個這樣的內置變量,例如,記錄分隔符變量RS、當前工作的記錄數NR等等。

示例:顯示文件本文件testAwk中第3行到第6行,以字符%分隔的第一個字段,第三個字段:

 awk -F % 'NR==3,NR==6 {printf $1  $3}' testAwk

示例:殺死系統中所有top進程

    ps -ef|grep " top" |grep -v "grep"|awk '{printf $2}'|xargs kill -9

    kill -9 `ps -ef|grep " top" |grep -v "grep"|awk '{printf $2}'`

五. awk的內置函數
1. 以上示例了printf函數,它與C語言相似,如下,顯示testAwk文件中行號與第1個字段:

  $awk '{printf"%03d%s\n",NR,$1}' testAwk

2. 顯示文本文件mydoc匹配(含有)字符串"sun"的所有行

   $awk '/sun/{print}' mydoc 

3.由於顯示整個記錄(全行)是awk的缺省動作,因此可以省略action項

   $awk '/sun/' mydoc 

4.示第一個匹配Sun或sun的行與第一個匹配Moon或moon的行之間的行,並顯示到標準輸出上:

    $awk '/[Ss]un/,/[Mm]oon/ {print}' myfile 

5.下面的示例顯示了內置變量和內置函數length()的使用:

   $awk 'length($0)>80 {print NR}' myfile 

6.UNIX中的用戶進行安全性檢查,方法是考察/etc下的passwd文件,檢查其中的passwd字段(第二字段)是否爲"*",如不爲"*",則表示該用戶沒有設置密碼,顯示出這些用戶名(第一字段)。我們可以用如下語句實現:

   #awk -F: '$2=="" {printf("%s no password!\n",$1' /etc/passwd

在這個示例中,passwd文件的字段分隔符是“:”,因此,必須用-F:來更改默認的字段分隔符,這個示例中也涉及到了內置函數printf的使用

六. awk的變量
awk提供兩種變量:
(1) 內置變量
  在引用時,不需要加$
(2) 自定義變量
awk中引用自定義變量必須在它前面加上標誌符"$"。awk根據其在awk中第一次出現的形式和上下文確定其具體的數據類型。當變量類型不確定時,awk默認其爲字符串類型。這裏有一個技巧:如果你要讓你的awk程序知道你所使用的變量的明確類型,你應當在在程序中給它賦初值。

七.運算與判斷
awk 支持多種運算,這些運算與C語言提供的幾本相同:如+、-、*、/、%等等,同時,awk也支持C語言中類似++、--、+=、-=、=+、=-之類的功 能,這給熟悉C語言的使用者編寫awk程序帶來了極大的方便。作爲對運算功能的一種擴展,awk還提供了一系列內置的運算函數(如log、sqr、 cos、sin等等)和一些用於對字符串進行操作(運算)的函數(如length、substr等等)。這些函數的引用大大的提高了awk的運算功能。

作 爲對條件轉移指令的一部分,關係判斷是每種程序設計語言都具備的功能,awk也不例外。awk中允許進行多種測試,如常用的==(等於)、!=(不等 於)、>(大於)、<(小於)、>=(大於等於)、>=(小於等於)等等,同時,作爲樣式匹配,還提供了~(匹配於)和!~(不 匹配於)判斷。

作爲對測試的一種擴充,awk也支持用邏輯運算符:!(非)、&&(與)、||(或)和括號()進行多重判斷,這大大增強了awk的功能。本文的附錄中列出了awk所允許的運算、判斷以及操作符的優先級。

八. awk的流程控制
1. BEGIN和END:
任何在BEGIN之後列出的操作(在{}內)將在awk開始掃描輸入之前執行,而END之後列出的操作將在掃描完全部的輸入之後執行。因此,通常使用BEGIN來顯示變量和預置(初始化)變量,使用END來輸出最終結果。
例:累計銷售文件xs中的銷售金額(假設銷售金額在記錄的第三字段):

$awk 
>'BEGIN { FS=":";print "統計銷售金額";total=0} 
>{print $3;total=total+$3;} 
>END {printf "銷售金額總計:%.2f",total}' sx 

(注:>是shell提供的第二提示符,如要在shell程序awk語句和awk語言中換行,則需在行尾加反斜槓\)

在這裏,BEGIN預置了內部變量FS(字段分隔符)和自定義變量total,同時在掃描之前顯示出輸出行頭。而END則在掃描完成後打印出總合計。

2. 流程控制語句
(1) if .. else
if...else語句
格式:
if(表達式)
語句1
else
語句2

if(表達式1)
{if(表達式2)
語句1
else
語句2
}
語句3
else {if(表達式3)
語句4
else
語句5
}
語句6
(2) while語句
格式爲:

while(表達式)
語句
(3)do-while語句
格式爲:
do
{
語句
}while(條件判斷語句)

(4) for語句
for(初始表達式;終止條件;步長表達式)
{語句}

在 awk的 while、do-while和for語句中允許使用break,continue語句來控制流程走向,也允許使用exit這樣的語句來退出。break 中斷當前正在執行的循環並跳到循環外執行下一條語句。continue從當前位置跳到循環開始處執行。對於exit的執行有兩種情況:當exit語句不在 END中時,任何操作中的exit命令表現得如同到了文件尾,所有模式或操作執行將停止,END模式中的操作被執行。而出現在END中的exit將導致程序終止。

九.awk中的自定義函數
原始的awk並不提供函數功能,只有在nawk或較新的awk版本中纔可以增加函數
awk函數的定義方法如下:

function 函數名(參數表){
函數體
}
在gawk中允許將function省略爲func,但其它版本的awk不允許。在 awk中調用函數比較簡單,其方法與C語言相似,但awk比C語言更爲靈活,它不執行參數有效性檢查。換句話說,在你調用函數時,可以列出比函數預計(函 數定義中規定)的多或少的參數,多餘的參數會被awk所忽略,而不足的參數,awk將它們置爲缺省值0或空字符串,具體置爲何值,將取決於參數的使用方 式。在函數中使用形如:return 返回值 格式的語句。
例: 下面的例子演示了函數的使用。在這個示例中,定義了一個名爲print_header的函數,該函數調用了兩個參數FileName和 PageNum,FileName參數傳給函數當前使用的文件名,PageNum參數是當前頁的頁號。這個函數的功能是打印(顯示)出當前文件的文件名, 和當前頁的頁號。完成這個功能後,這個函數將返回下一頁的頁號。

nawk 
>'BEGIN{pageno=1;file=FILENAME 
>pageno=print_header(file,pageno);#調用函數print_header 
>printf("當前頁頁號是:%d\n",pageno); 
>} 
>#定義函數print_header 
>function print_header(FileName,PageNum){ 
>printf("%s %d\n",FileName,PageNum); >PageNum++;return PageNUm; 
>} 
>}' myfile 

執行這個程序將顯示如下內容:
myfile 1
當前頁頁號是:2

十.awk高級輸入輸出
1.讀取下一條記錄:
awk的next語句導致awk讀取下一個記錄並完成模式匹配,然後立即執行相應的操作。通常它用匹配的模式執行操作中的代碼。next導致這個記錄的任何額外匹配模式被忽略。

2.簡單地讀取一條記錄
awk 的 getline語句用於簡單地讀取一條記錄。如果用戶有一個數據記錄類似兩個物理記錄,那麼getline將尤其有用。它完成一般字段的分離(設置字段變 量$0 FNR NF NR)。如果成功則返回1,失敗則返回0(到達文件尾)。如果需簡單地讀取一個文件,則可以編寫以下代碼:
例:示例getline的使用

{while(getline==1) 
{ 
#process the inputted fields 
} 
} 

也可以使getline保存輸入數據在一個字段中,而不是通過使用getline variable的形式處理一般字段。當使用這種方式時,NF被置成0,FNR和NR被增值。
用 戶也可以使用getline<"filename"方式從一個給定的文件中輸入數據,而不是從命令行所列內容輸入數據。此時,getline將完成 一般字段分離(設置字段變量$0和NF)。如果文件不存在,返回-1,成功,返回1,返回0表示失敗。用戶可以從給定文件中讀取數據到一個變量中,也可以 用stdin(標準輸入設備)或一個包含這個文件名的變量代替filename。值得注意的是當使用這種方式時不修改FNR和NR。

另一種使用getline語句的方法是從UNIX命令接受輸入,例如下面的例子:
例:示例從UNIX命令接受輸入

{while("who -u"|getline) 
{ 
#process each line from the who command 
} 
} 

當然,也可以使用如下形式:

"command" | getline variable 

3.關閉文件:
awk中允許在程序中關閉一個輸入或輸出文件,方法是使用awk的close語句。
close("filename")
filename可以是getline打開的文件(也可以是stdin,包含文件名的變量或者getline使用的確切命令)。或一個輸出文件(可以是stdout,包含文件名的變量或使用管道的確切命令)。

4.輸出到一個文件:
awk中允許用如下方式將結果輸出到一個文件:

printf("hello word!\n")>"datafile" 

printf("hello word!\n")>>"datafile" 

5.輸出到一個命令
awk中允許用如下方式將結果輸出到一個命令:

printf("hello word!\n")|"sort-t','" 

十一.awk與shell script混合編程
因 爲awk可以作爲一個shell命令使用,因此awk能與shell批處理程序很好的融合在一起,這給實現awk與shell程序的混合編程提供了可能。 實現混合編程的關鍵是awk與shell script之間的對話,換言之,就是awk與shell script之間的信息交流:awk從shell script中獲取所需的信息(通常是變量的值)、在awk中執行shell命令行、shell script將命令執行的結果送給awk處理以及shell script讀取awk的執行結果等等。

1.awk讀取Shell script程序變量
在awk中我們可以通過“'$變量名'”的方式讀取sell scrpit程序中的變量。
例:在下面的示例中,我們將讀取sell scrpit程序中的變量Name,該變量存放的是文本myfile的撰寫者,awk將打印出這個人名。

$cat writename 
: 
# @(#) 
# 
. 
. 
. 
Name="張三" nawk 'BEGIN {name="'Name'";\ printf("\t%s\t撰寫者%s\n",FILENAME,name");}\ 
{...}END{...}' myfile 
. 
. 
. 

2.將shell命令的執行結果送給awk處理
作爲信息傳送的一種方法,我們可以將一條shell命令的結果通過管道線(|)傳遞給awk處理:
例:示例awk處理shell命令的執行結果

$who -u | awk '{printf("%s正在執行%s\n",$2,$1)}' 

該命令將打印出註冊終端正在執行的程序名。

3.shell script程序讀awk的執行結果
爲 了實現shell script程序讀取awk執行的結果,我們可以採取一些特殊的方法,例如我們可以用變量名=`awk語句`的形式將awk執行的結果存放入一個 shell script變量。當然也可以用管道線的方法將awk執行結果傳遞給shell script程序處理。
例:作爲傳送消息 的機制之一,UNIX提供了一個向其所有用戶傳送消息的命令wall(意思是write to all寫給所有用戶),該命令允許向所有工作中的用戶(終端)發送消息。爲此,我們可以通過一段shell批處理程序wall.shell來模擬這一程序 (事實上比較老的版本中wall就是一段shell批處理程序:

$cat wall.shell 
: 
# @(#) wall.shell:發送消息給每個已註冊終端 
# 
cat >/tmp/$$ 

#用戶錄入消息文本 who -u | awk '{print $2}' | while read tty 
do 
cat /tmp/$$>$tty 
done 

在 這個程序裏,awk接受who -u命令的執行結果,該命令打印出所有已註冊終端的信息,其中第二個字段是已註冊終端的設備名,因此用awk命令析出該設備名,然後用while read tty語句循環讀出這些文件名到變量(shell script變量)tty中,作爲信息傳送的終結地址。

4.在awk中執行shell命令行----嵌入函數system()
system()是一個不適合字符或數字類型的嵌入函數,該函數的功能是處理作爲參數傳遞給它的字符串。system對這個參數的處理就是將其作爲命令處理,也就是說將其當作命令行一樣加以執行。這使得用戶在自己的awk程序需要時可以靈活地執行命令或腳本。
例:下面的程序將使用system嵌入函數打印用戶編制好的報表文件,這個文件存放在名爲myreport.txt的文件中。爲簡約起見,我們只列出了其END部分:
.
.
.
END {close("myreport.txt");system("lp myreport.txt");}
在這個示例中,我們首先使用close語句關閉了文件myreport.txt文件,然後使用system嵌入函數將myreport.txt送入打印機打印。

十二附錄:

1.awk的常規表達式元字符
\ 換碼序列
^ 在字符串的開頭開始匹配
$ 在字符串的結尾開始匹配
. 與任何單個字符串匹配
[ABC] 與[]內的任一字符匹配
[A-Ca-c] 與A-C及a-c範圍內的字符匹配(按字母表順序)
[^ABC] 與除[]內的所有字符以外的任一字符匹配
Desk|Chair 與Desk和Chair中的任一個匹配
[ABC][DEF] 關聯。與A、B、C中的任一字符匹配,且其後要跟D、E、F中的任一個字符。
* 與A、B或C中任一個出現0次或多次的字符相匹配
+ 與A、B或C中任何一個出現1次或多次的字符相匹配
? 與一個空串或A、B或C在任何一個字符相匹配
(Blue|Black)berry 合併常規表達式,與Blueberry或Blackberry相匹配

2.awk算術運算符
運算符 用途
------------------
x^y x的y次冪
x**y 同上
x%y 計算x/y的餘數(求模)
x+y x加y
x-y x減y
x*y x乘y
x/y x除y
-y 負y(y的開關符號);也稱一目減
++y y加1後使用y(前置加)
y++ 使用y值後加1(後綴加)
--y y減1後使用y(前置減)
y-- 使用後y減1(後綴減)
x=y 將y的值賦給x
x+=y 將x+y的值賦給x
x-=y 將x-y的值賦給x
x*=y 將x*y的值賦給x
x/=y 將x/y的值賦給x x%=y 將x%y的值賦給x
x^=y 將x^y的值賦給x
x**=y 將x**y的值賦給x

3.awk允許的測試:
操作符 含義
x==y x等於y
x!=y x不等於y
x>y x大於y
x>=y x大於或等於y
x x<=y x小於或等於y?
x~re x匹配正則表達式re?
x!~re x不匹配正則表達式re?

4.awk的操作符(按優先級升序排列)
= 、+=、 -=、 *= 、/= 、 %=
||
&&
> >= < <= == != ~ !~
xy (字符串連結,'x''y'變成"xy")
+ -
* / %
++ --

5.awk內置變量(預定義變量)
說明:表中v項表示第一個支持變量的工具(下同):A=awk,N=nawk,P=POSIX awk,G=gawk
V 變量 含義 缺省值
--------------------------------------------------------
N ARGC 命令行參數個數
G ARGIND 當前被處理文件的ARGV標誌符
N ARGV 命令行參數數組
G CONVFMT 數字轉換格式 %.6g
P ENVIRON UNIX環境變量
N ERRNO UNIX系統錯誤消息
G FIELDWIDTHS 輸入字段寬度的空白分隔字符串
A FILENAME 當前輸入文件的名字
P FNR 當前記錄數
A FS 輸入字段分隔符 空格
G IGNORECASE 控制大小寫敏感0(大小寫敏感)
A NF 當前記錄中的字段個數
A NR 已經讀出的記錄數
A OFMT 數字的輸出格式 %.6g
A OFS 輸出字段分隔符 空格
A ORS 輸出的記錄分隔符 新行
A RS 輸入的記錄他隔符 新行
N RSTART 被匹配函數匹配的字符串首
N RLENGTH 被匹配函數匹配的字符串長度
N SUBSEP 下標分隔符 "\034"

6.awk的內置函數
V 函數 用途或返回值
------------------------------------------------
N gsub(reg,string,target) 每次常規表達式reg匹配時替換target中的string
N index(search,string) 返回string中search串的位置
A length(string) 求串string中的字符個數
N match(string,reg) 返回常規表達式reg匹配的string中的位置
N printf(format,variable) 格式化輸出,按format提供的格式輸出變量variable。
N split(string,store,delim) 根據分界符delim,分解string爲store的數組元素
N sprintf(format,variable) 返回一個包含基於format的格式化數據,variables是要放到串中的數據
G strftime(format,timestamp) 返回一個基於format的日期或者時間串,timestmp是systime()函數返回的時間
N sub(reg,string,target) 第一次當常規表達式reg匹配,替換target串中的字符串
A substr(string,position,len) 返回一個以position開始len個字符的子串
P totower(string) 返回string中對應的小寫字符
P toupper(string) 返回string中對應的大寫字符
A atan(x,y) x的餘切(弧度)
N cos(x) x的餘弦(弧度)
A exp(x) e的x冪
A int(x) x的整數部分
A log(x) x的自然對數值
N rand() 0-1之間的隨機數
N sin(x) x的正弦(弧度)
A sqrt(x) x的平方根
A srand(x) 初始化隨機數發生器。如果忽略x,則使用system()
G system() 返回自1970年1月1日以來經過的時間(按秒計算)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章