Linux文件比較三劍客(awk/grep/sed)之a(chǎn)wk

一、什么是awk


awkLinux下的一個(gè)命令,他對(duì)其他命令的輸出,對(duì)文件的處理都十分強(qiáng)大,其實(shí)他更像一門(mén)編程語(yǔ)言,他可以自定義變量,有條件語(yǔ)句,有循環(huán),有數(shù)組,有正則,有函數(shù)等。他讀取輸出,或者文件的方式是一行,一行的讀,根據(jù)你給出的條件進(jìn)行查找,并在找出來(lái)的行中進(jìn)行操作,感覺(jué)他的設(shè)計(jì)思想,真的很簡(jiǎn)單,但是結(jié)合實(shí)際情況,具體操作起來(lái)就沒(méi)有那么簡(jiǎn)單了。他有三種形勢(shì),awkgawknawk,平時(shí)所說(shuō)的awk其實(shí)就是gawk

二、awk命令格式和選項(xiàng)


·2.1 語(yǔ)法形式
awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)

·盡管操作可能會(huì)很復(fù)雜,但語(yǔ)法總是這樣,其中 pattern 表示 awk在數(shù)據(jù)中查找的內(nèi)容,而 action是在找到匹配內(nèi)容時(shí)所執(zhí)行的一系列命令。花括號(hào)({})不需要在程序中始終出現(xiàn),但它們用于根據(jù)特定的模式對(duì)一系列指令進(jìn)行分組。 pattern就是要表示的正則表達(dá)式,用斜杠括起來(lái)。

·awk語(yǔ)言的最基本功能是在文件或者字符串中基于指定規(guī)則瀏覽和抽取信息,awk抽取信息后,才能進(jìn)行其他文本操作。完整的awk腳本通常用來(lái)格式化文本文件中的信息。

·通常,awk是以文件的一行為處理單位的。awk每接收文件的一行,然后執(zhí)行相應(yīng)的命令,來(lái)處理文本。

·2.2 命令選項(xiàng)

-F fs or --field-separator fs
指定輸入文件折分隔符,fs是一個(gè)字符串或者是一個(gè)正則表達(dá)式,如-F:

-v var=value or --asign var=value
賦值一個(gè)用戶(hù)定義變量。

-f scripfile or --file scriptfile
從腳本文件中讀取awk命令。

-mf nnn and -mr nnn
對(duì)nnn值設(shè)置內(nèi)在限制,-mf選項(xiàng)限制分配給nnn的最大塊數(shù)目;
-mr選項(xiàng)限制記錄的最大數(shù)目。這兩個(gè)功能是Bell實(shí)驗(yàn)室版awk的擴(kuò)展功能,在標(biāo)準(zhǔn)awk中不適用。

-W compact or --compat, -W traditional or --traditional
在兼容模式下運(yùn)行awk。所以gawk的行為和標(biāo)準(zhǔn)的awk完全一樣,所有的awk擴(kuò)展都被忽略。

-W copyleft or --copyleft, -W copyright or --copyright
打印簡(jiǎn)短的版權(quán)信息。

-W help or --help, -W usage or --usage
打印全部awk選項(xiàng)和每個(gè)選項(xiàng)的簡(jiǎn)短說(shuō)明。

-W lint or --lint
打印不能向傳統(tǒng)unix平臺(tái)移植的結(jié)構(gòu)的警告。

-W lint-old or --lint-old
打印關(guān)于不能向傳統(tǒng)unix平臺(tái)移植的結(jié)構(gòu)的警告。

-W posix
打開(kāi)兼容模式。但有以下限制,不識(shí)別:\x、函數(shù)關(guān)鍵字、func、換碼序列以及當(dāng)fs是一個(gè)空格時(shí),將新行作為一個(gè)域分隔符;操作符****=不能代替^^=fflush無(wú)效。

-W re-interval or --re-inerval
允許間隔正則表達(dá)式的使用,參考(grep中的Posix字符類(lèi)),如括號(hào)表達(dá)式[[:alpha:]]

-W source program-text or --source program-text
使用program-text作為源代碼,可與-f命令混用。

-W version or --version
打印bug報(bào)告信息的版本。

三、awk的正則


匹配符 描述
\Y 匹配一個(gè)單詞開(kāi)頭或者末尾的空字符串
\B 匹配單詞內(nèi)的空字符串
< 匹配一個(gè)單詞的開(kāi)頭的空字符串,錨定開(kāi)始
> 匹配一個(gè)單詞的末尾的空字符串,錨定末尾
\W 匹配一個(gè)非字母數(shù)字組成的單詞
\w 匹配一個(gè)字母數(shù)字組成的單詞
' 匹配字符串末尾的一個(gè)空字符串
\‘ 匹配字符串開(kāi)頭的一個(gè)空字符串

四、awk的函數(shù)


·4.1 字符串函數(shù)
函數(shù)名 描述
sub 匹配記錄中最大、最靠左邊的子字符串的正則表達(dá)式,并用替換字符串替換這些字符串。如果沒(méi)有指定目標(biāo)字符串就默認(rèn)使用整個(gè)記錄。替換只發(fā)生在第一次匹配的 時(shí)候
gsub 整個(gè)文檔中進(jìn)行匹配
index 返回子字符串第一次被匹配的位置,偏移量從位置1開(kāi)始
substr 返回從位置1開(kāi)始的子字符串,如果指定長(zhǎng)度超過(guò)實(shí)際長(zhǎng)度,就返回整個(gè)字符串
split 可按給定的分隔符把字符串分割為一個(gè)數(shù)組。如果分隔符沒(méi)提供,則按當(dāng)前FS值進(jìn)行分割
length 返回記錄的字符數(shù)
match 返回在字符串中正則表達(dá)式位置的索引,如果找不到指定的正則表達(dá)式則返回0。match函數(shù)會(huì)設(shè)置內(nèi)建變量RSTART為字符串中子字符串的開(kāi)始位 置,RLENGTH為到子字符串末尾的字符個(gè)數(shù)。substr可利于這些變量來(lái)截取字符串
toupper和tolower 可用于字符串大小間的轉(zhuǎn)換,該功能只在gawk中有效
·4.2 數(shù)學(xué)函數(shù)
函數(shù)名 返回值
atan2(x,y) y,x 范圍內(nèi)的余切
cos(x) 余弦函數(shù)
exp(x) 求 冪
int(x) 取整
log(x) 自然對(duì) 數(shù)
rand() 隨機(jī)數(shù)
sin(x) 正弦
sqrt(x) 平 方根
srand(x) x是rand()函數(shù)的種子
int(x) 取 整,過(guò)程沒(méi)有舍入
rand() 產(chǎn)生一個(gè)大于等于0而小于1的隨機(jī)數(shù)

五、入門(mén)實(shí)例


·假設(shè)last -n 5的輸出如下

[root@www ~]# last -n 5 <==僅取出前五行
root     pts/1   192.168.1.100  Tue Feb 10 11:21   still logged in
root     pts/1   192.168.1.100  Tue Feb 10 00:46 - 02:28  (01:41)
root     pts/1   192.168.1.100  Mon Feb  9 11:41 - 18:30  (06:48)
dmtsai   pts/1   192.168.1.100  Mon Feb  9 11:41 - 11:41  (00:00)
root     tty1                   Fri Sep  5 14:09 - 14:10  (00:01)

·如果只是顯示最近登錄的5個(gè)帳號(hào)

#last -n 5 | awk  '{print $1}'
root
root
root
dmtsai
root

·awk工作流程是這樣的:讀入有'\n'換行符分割的一條記錄,然后將記錄按指定的域分隔符劃分域,填充域,$0則表示所有域,$1表示第一個(gè)域,$n表示第n個(gè)域。默認(rèn)域分隔符是"空白鍵" 或[tab]鍵,所以$1表示登錄用戶(hù),$3表示登錄用戶(hù)ip,以此類(lèi)推。

·如果只是顯示/etc/passwd的賬戶(hù)

#cat /etc/passwd |awk  -F ':'  '{print $1}'  
root
daemon
bin
sys

·這種是awk+action的示例,每行都會(huì)執(zhí)行action{print $1}

-F指定域分隔符為':'

·如果只是顯示/etc/passwd的賬戶(hù)和賬戶(hù)對(duì)應(yīng)的shell,而賬戶(hù)與shell之間以tab鍵分割

#cat /etc/passwd |awk  -F ':'  '{print $1"\t"$7}'
root    /bin/bash
daemon  /bin/sh
bin     /bin/sh
sys     /bin/sh

·如果只是顯示/etc/passwd的賬戶(hù)和賬戶(hù)對(duì)應(yīng)的shell,而賬戶(hù)與shell之間以逗號(hào)分割,而且在所有行添加列名name,shell,在最后一行添加"blue,/bin/nosh"

cat /etc/passwd |awk  -F ':'  'BEGIN {print "name,shell"}  {print $1","$7} END {print "blue,/bin/nosh"}'
name,shell
root,/bin/bash
daemon,/bin/sh
bin,/bin/sh
sys,/bin/sh
....
blue,/bin/nosh

·awk工作流程是這樣的:先執(zhí)行BEGING,然后讀取文件,讀入有/n換行符分割的一條記錄,然后將記錄按指定的域分隔符劃分域,填充域,$0則表示所有域,$1表示第一個(gè)域,$n表示第n個(gè)域,隨后開(kāi)始執(zhí)行模式所對(duì)應(yīng)的動(dòng)作action。接著開(kāi)始讀入第二條記錄······直到所有的記錄都讀完,最后執(zhí)行END操作。

·搜索/etc/passwdroot關(guān)鍵字的所有行

#awk -F: '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash

·這種是pattern的使用示例,匹配了pattern(這里是root)的行才會(huì)執(zhí)行action(沒(méi)有指定action,默認(rèn)輸出每行的內(nèi)容)。

·搜索支持正則,例如找root開(kāi)頭的: awk -F: '/^root/' /etc/passwd

·搜索/etc/passwdroot關(guān)鍵字的所有行,并顯示對(duì)應(yīng)的shell

# awk -F: '/root/{print $7}' /etc/passwd             
/bin/bash

這里指定了action{print $7}


參考文獻(xiàn):

http://man.lupaworld.com/content/manage/ringkee/awk.htm
http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html
http://www.codeweblog.com/awk命令-awk編程語(yǔ)言詳細(xì)介紹和實(shí)例/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容