awk 可以勝任幾乎所有的文本處理工作。
awk
調(diào)用
1.調(diào)用 awk:
方式一:命令行方式
awk [-F field-separator ] ‘commands’ input-file(s)
[ -F 域分隔符 ]是可選的,因為 awk 使用空格作為缺省的域分隔符,因此如果要瀏覽域間有空格的文本,不必指定這個選項,如果要瀏覽例如 passwd 文件.此文件名域以冒號作為分隔符,則必須指明-F 選項,如:
awk -F ‘commands’ input-file
方式二:將所有 awk 命令插入一個文件,并使阿瓦庫程序可執(zhí)行,然后用 awk 命令解釋器作為腳本的首行,以便通過鍵入腳本名成功來調(diào)用它.
方式三:將所有的 awk 命令插入一個單純文件,然后調(diào)用:
awk -f awk-script-file input-file(s)
-f 選項指明在文件 awk_script_file 中的 awk 腳本,input_file(s)是使用 awk 進(jìn)行瀏覽的文件名.
任何 awk 語句都是有模式和動作組成.在一個 awk 腳本中可能有很多語句,模式部分決定動作語句何時觸發(fā)以及出發(fā)時間.處理即對數(shù)據(jù)進(jìn)行的操作.如果省略模式部分,動作將時刻保持執(zhí)行狀態(tài).模式可以是任何條件語句或符合語句或正則表達(dá)式.模式包括兩個特殊字段 BEGIN 和 END.使用 BEGIN 語句設(shè)置計數(shù)和打印頭.BEGIN 語句使用在任何文本瀏覽動作之前,之后文本瀏覽動作一句輸入文本開始執(zhí)行.END 語句用來在 awk 完成瀏覽動作后打印輸出文本總數(shù)和結(jié)尾狀態(tài)標(biāo)識.
使用$1,$3 表示參照第一個和第三個域,注意這里使用逗號做域分割,如果希望打印一個有 5 個域的記錄的所有域,可使用$0,意即所有域.
為打印一個域或所有域,使用 printf 命令,這是一個 awk 動作
模式:兩個特殊段 BEGIN 和 END
動作:實際動作大多在{}內(nèi)指明
輸出:
抽取域
命令:awk -F: '{print $1}' /etc/passwd
輸出:打印/etc/passwd 目錄下的所有用戶名
保存輸出
awk -F: ‘{print $1}’ /etc/passwd |tee user 使用 tee 命令,在輸出文件的同時,輸出到屏幕
awk -F : ‘{print $1}’ /etc/passwd > user3awk -F : ‘{print $0}’ /etc/passwd 打印單獨記錄
awk -F: ‘{print $1,$4}’ /etc/passwd
打印報告頭
awk -F : ‘BEGIN{print “NAME\n”}{print $1}’ /etc/passwd
awk -F: ‘{print $1}END{print “this is all users\n”}’ /etc/passwd 條件操作符
匹配
awk -F : '{if($1~/root/) print}' /etc/passwd
分析:if($1~/roo/t) 表示如果 file 中包含 root,打印他
精確匹配
使用符號==
awk -F: '{if($3==0) print}' /etc/passwd
不匹配
!~
awk -F: '{if($1!~/linuxone/) print}' /etc/passwd
精確不匹配
!=
awk -F: '{if($1!=/linuxone/) print}' /etc/passwd
設(shè)置大小寫
awk ‘/[Rr]oot’ /etc/passwd
任意字符
awk -F : '{f($1~/^...t/) print}' /etc/passwd
分析:if($1~/^...t/)表示第四個字母是 t
或關(guān)系匹配
awk -F : '{if($1~/(squid|nagios)/) print}' /etc/passwd
行首
awk '/^root/' /etc/passwd
分析:^root(行首包含 root)
AND &&
awk -F : '{if($1=="root"&&$3=="0") print}' /etc/passwd
內(nèi)置變量:
|
變量名 |
含義 |
|
ARCC |
命令行參數(shù)個數(shù) |
|
ARGV |
命令行參數(shù)列表 |
|
ENV?|RON |
支持隊列中的系統(tǒng)環(huán)境變量的使用 |
|
FNR |
瀏覽文件的記錄數(shù) |
|
FS |
置頂分隔符,等價于-F |
|
NF |
瀏覽記錄的域的個數(shù) |
|
NR |
一度的記錄數(shù) |
|
OFS |
輸出域分隔符 |
|
ORS |
輸出記錄分隔符 |
|
RS |
控制記錄分隔符 |
案例:
打印有多少行記錄
awk 'END{print NR}' /etc/passwd
設(shè)置輸入域到變量名
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=="root"){$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的后綴部分 |
awk 'gsub(/^root/,"netseek") {print}' /etc/passwd #將以root開頭的字符串替換為netseek并打印 awk 'gsub(/0/,2){print}' /etc/passwd
awk '{print gsub(/0/,2) $0}' /etc/fstab
awk 'BEGIN{print index("root","o")}' #查詢o在root字符串中出現(xiàn)的第一位置awk -F : '$1=="root" {print index($1,"o")" " $1}' /etc/passwd
awk -F : '{print index($1,"o") $1}' /etc/passwd
awk -F : '{print length($1)}' /etc/passwdwk -F : '$1=="root"{print length($1)"\t" $0}' /etc/passwd
match(在 ANCD 中查找 C 的位置)
awk 'BEGIN{print match("ANCD","C")}'
split 返回字符串?dāng)?shù)組元素個數(shù)
awk 'BEGIN{print split("123#456#789",array,"#")}'
sub 只能替換指定域的第一個 0
awk 'sub(/0/,2){print }' /etc/fstab
awk 'BEGIN{print substr("www.baidu.com",5,9)}' #第五個子夫開始,取9個字符awk 'BEGIN{print substr("www.baidu.com",5)}' #第五個位置開始,一直到最后
字符串屏蔽序列
| 符號 | 含義 |
|---|---|
| \b | 退格符 |
| \f | 走紙換頁 |
| \n | 新行 |
| \r | 回車 |
| \t | tab鍵(四個空格) |
| \c | 任意其他特殊字符 |
| \ddd | 八進(jìn)制 |
案例:
awk -F : '{print $1,"\b" $2,"\t" $3}' /etc/passwd
分析:print 和 printf 兩者效果不同
printf 修飾符
awk printf 格式
| 符號 | 含義 |
|---|---|
| %c | ASCII 字符 |
| %d | 整數(shù) |
| %e | 科學(xué)計數(shù)法 |
| %f | 浮點數(shù) |
| %g | awk 決定使用哪種浮點數(shù)轉(zhuǎn)換,e 或者 f |
| %o | 八進(jìn)制數(shù) |
| %s | 字符串 |
| %x | 十六進(jìn)制 |
echo "65" | awk '{printf "%c\n", $0}'awk 'BEGIN{printf "%c\n" ,65}'
awk 'BEGIN{printf "%f\n",999}'
awk -F : '{printf "%-15s %s\n",$1,$3}' /etc/passwdawk -F : 'BEGIN{printf "USER\t\tUID\n"}{printf "%-15s %s\n",$1,$3}' /etc/passwd
向一行 awk 命令傳值
who | awk '{if ($1==user) print $1 " you are connected :" $2}' user=$LOGNAME
#!/bin/awk -f
BEGIN{
FS=":"
print "User\t\tUID"
print "----------------"
}
{printf "%-15s %s\n",$1,$3}
END{
print "end"
}
分析:awk 腳本文件開頭一般都是這樣的:#!/bin/awk -f
已經(jīng)指明了 -f 選項。
執(zhí)行時,直接在 awk 腳本名后面加要處理的文件名作為參數(shù)即可。