shell awk的用法

awk
調用:
1.調用awk:

第一種方式:命令行方式
awk [-F field-separator] 'commands' input-file(s)
[-F域分隔符]是可選的,因爲awk使用空格作爲缺省的域分隔符,因此如果要瀏覽域間有空格的文本,不必指定這個選項,如果要瀏覽諸如passwd文件,此文件各域以冒號作爲分隔符,則必須指明-F選項,如:
awk -F: 'commands' input-file

第二種方式是將所有awk命令插入一個文件,並使awk程序可執行,然後用awk命令解釋器作爲腳本的首行,以便通過鍵入腳本名稱來調用它。

第三種方式是將所有的awk命令插入一個單獨文件,然後調用:
awk -f awk-scrīpt-file input-files(s)
-f選項指明在文件awk_scrīpt_file中的awk腳本,input_file(s)是使用awk進行瀏覽的文件名。 


模式和動作

任何awk語句都由模式和動作組成。在一個awk腳本中可能有許多語句。模式部分決定動作語句何時觸發及觸發事件。處理即對數據進行的操作。如果省略模式部分,動作將時刻保持執行狀態。模式可以是任何條件語句或複合語句或正則表達式。模式包括兩個特殊字段 BEGIN和END。使用BEGIN語句設置計數和打印頭。BEGIN語句使用在任何文本瀏覽動作之前,之後文本瀏覽動作依據輸入文本開始執行。END語句用來在awk完成文本瀏覽動作後打印輸出文本總數和結尾狀態標誌。

域和記錄
使用$1,$3表示參照第1和第3域,注意這裏用逗號做域分隔。如果希望打印一個有5個域的記錄的所有域,可使用$0,意即所有域。
爲打印一個域或所有域,使用print命令。這是一個awk動作

模式和動作
模式:兩個特殊斷 BEGIN和END
動作:實際動作大多在{}內指明


輸出
1.抽取域
awk -F: '{print $1}' /etc/passwd

2.保存輸出
awk -F: '{print $1}' /etc/passwd | tee user 使用tee命令,在輸出文件的同時,輸出到屏幕

使用標準輸出
awk -F: '{print $1}' /etc/passwd >user3

4.打印所有記錄
awk -F: '{print $0}' /etc/passwd

5.打印單獨記錄
awk -F: '{print $1,$4}' /etc/passwd

6.打印報告頭
awk -F: 'BEGIN {print "NAME\n"} {print $1}' /etc/passwd

7.打印結尾
awk -F: '{print $1} END {print "this is all users"}' /etc/passwd


條件操作符
1.匹配
awk -F: '{if($1~/root/) print }' /etc/passwd      //{if($1~/root/) print}表示如果field1包含root,打印它

2.精確匹配
使用等號 ==
awk -F: '{if($3=="0") print }' /etc/passwd  

3.不匹配
!~
awk -F: '{if($1!~/linuxtone/) print }' /etc/passwd

!=
精確不匹配
awk -F: '{if($1!="linuxtone") print }' /etc/passwd

4.小於
<
5.小於等於
<=
6.大於
>
.........
7.設置大小寫
awk '/[Rr]oot/' /etc/passwd

8.任意字符
awk -F: '{if($1~/^...t/) print}' /etc/passwd      //^...t表示第四個字幕是t

9.或關係匹配
awk -F: '{if ($1~/(squid|nagios)/) print}' /etc/passwd

10.行首
awk '/^root/' /etc/passwd       // ^root(行首包含root)

11.AND &&
awk -F: '{if($1=="root" && $3=="0") print}' /etc/passwd

12.OR ||

內置變量:
ARCC                                      命令行參數個數
ARGV                                      命令行參數排列
ENVIRON                                   支持隊列中系統環境變量的使用
FNR                                       瀏覽文件的記錄數
FS                                        置頂分隔符,等價於-F
NF                                        瀏覽記錄的域的個數
NR                                        已讀的記錄數
OFS                                       輸出域分隔符
ORS                                       輸出記錄分隔符
RS                                        控制記錄分隔符

打印有多少行記錄
awk 'END {print NR}' /etc/passwd

設置輸入域到變量名
awk -F: '{name=$1; path=$7; if(name~/root/) print name  "\tpath is:" path}' /etc/passwd

域值比較操作
awk '{if($6<$7) print $0}' input-file

修改文本域只顯示修改改記錄
awk -F: '{if($1=="nagios") {$1="nagios server" ; print }}' /etc/passwd

文件長度相加
ls -l|awk '/^[^d]/ {print $9"\t" $5} {tot+=$5} END {print "total kb:"tot}'

內置的字符竄函數
gsub(r,s)                                                      在整個$0中用s替代r
gsub(r,s,t)                                                    在整個t中用s替代r
index(s,t)                                                     返回s中字符串t的第一位置
length(s)                                                      返回s長度
match(s,r)                                                     測試s中是否包含匹配r的字符串
split(s,a,fs)                                                  在fs上將s分成序列a
sub(s, )                                                       用$0中最左邊也是最長的字符串替代
subtr(s,p)                                                     返回字符串s中從p開始的後綴部分
substr(s,p,n)                                                  返回字符串s中從p開始長度爲n的後綴部分

1.gsub
awk 'gsub(/^root/,"netseek") {print}' /etc/passwd             將與root開頭的root替換爲netseek

awk 'gsub(/0/,2) {print}' /etc/fstab 

awk '{print gsub(/0/,2) $0}' /etc/fstab                       

2.index
awk 'BEGIN {print index("root","o")}'  查詢字符串root中o出現的第一位置

awk -F: '$1=="root" {print index($1,"o")" "$1}' /etc/passwd

awk -F: '{print index($1,"o") $1}' /etc/passwd

3.length
awk -F: '{print length($1)'} /etc/passwd

awk -F: '$1=="root" {print length($1)}' /etc/passwd

4.match (在ANCD中查找C的位置)
awk 'BEGIN {print match("ANCD",/C/)}'

5.split
返回字符串數組元素個數
awk 'BEGIN {print split("123#456#789", myarray, "#")}'

6.sub   只能替換指定域的第一個0
awk 'sub(/0/,2) {print }' /etc/fstab

7.substr 
按照起始位置及長度返回字符串的一部分
awk 'BEGIN {print substr("www.linuxtone.org",5,9)}'  //第5個字符開始,取9個字符。

awk 'BEGIN {print substr("www.linuxtone.org",5)}'  //第5個位置開始,取後面的所有.

字符串屏蔽序列
\b                  退格鍵
\f                  走紙換頁
\n                  新行
\r                  回車
\t                  tab
\c                  任意其他特殊字符
\ddd                八進制

很簡單的例子
awk -F: '{print $1,"\b"$2,"\t"$3}' /etc/passwd 輸出函數printf(注意是printf不是print,兩者效果不同的)
printf函數擁有幾種不同的格式化輸出功能

printf修飾符
-                               左對齊
Width                        域的步長0表示0步長
.prec                          最大字符串長度,或小數點右邊的位數


awk printf格式
%c                              ASCII字符
%d                              整數
%e                              浮點數,科學計數法
%f                               浮點數
%g                              awk決定使用哪種浮點數轉換,e或者f
%o                              八進制數
%s                              字符串
%x                              十六進制數

1.字符串轉換
echo "65" | awk '{printf"%c\n",$0}'

awk 'BEGIN {printf "%c\n",65}'

awk 'BEGIN {printf "%f\n",999}'

2.格式化輸出
awk -F: '{printf "%-15s %s\n",$1,$3}' /etc/passwd

awk -F: 'BEGIN {printf"USER\t\tUID\n"} {printf "%-15s %s\n",$1,$3}' /etc/passwd

3.向一行awk命令傳值
who | awk '{if ($1 == user) print $1 " you are connected to:" $2}' user=$LOGNAME

4.awk腳本文件 (在文件名字後面加後綴.awk方便區分)
#!/bin/awk -f
BEGIN{
    FS=":"
        print "User\t\tUID"
        print"____________________________"
}

{printf "%-15s %s\n",$1,$3}

END{
       print "END"

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