awk 可以勝任幾乎所有的文本處理工作。
awk
調(diào)用
1.調(diào)用 awk:
方式一:命令行方式
awk [-F field-separator ] ‘commands’ input-file(s)
[ -F 域分隔符 ]是可選的,因?yàn)?awk 使用空格作為缺省的域分隔符,因此如果要瀏覽域間有空格的文本,不必指定這個(gè)選項(xiàng),如果要瀏覽例如 passwd 文件.此文件名域以冒號(hào)作為分隔符,則必須指明-F 選項(xiàng),如:
awk -F ‘commands’ input-file
方式二:將所有 awk 命令插入一個(gè)文件,并使阿瓦庫(kù)程序可執(zhí)行,然后用 awk 命令解釋器作為腳本的首行,以便通過(guò)鍵入腳本名成功來(lái)調(diào)用它.
方式三:將所有的 awk 命令插入一個(gè)單純文件,然后調(diào)用:
awk -f awk-script-file input-file(s)
-f 選項(xiàng)指明在文件 awk_script_file 中的 awk 腳本,input_file(s)是使用 awk 進(jìn)行瀏覽的文件名.
任何 awk 語(yǔ)句都是有模式和動(dòng)作組成.在一個(gè) awk 腳本中可能有很多語(yǔ)句,模式部分決定動(dòng)作語(yǔ)句何時(shí)觸發(fā)以及出發(fā)時(shí)間.處理即對(duì)數(shù)據(jù)進(jìn)行的操作.如果省略模式部分,動(dòng)作將時(shí)刻保持執(zhí)行狀態(tài).模式可以是任何條件語(yǔ)句或符合語(yǔ)句或正則表達(dá)式.模式包括兩個(gè)特殊字段 BEGIN 和 END.使用 BEGIN 語(yǔ)句設(shè)置計(jì)數(shù)和打印頭.BEGIN 語(yǔ)句使用在任何文本瀏覽動(dòng)作之前,之后文本瀏覽動(dòng)作一句輸入文本開始執(zhí)行.END 語(yǔ)句用來(lái)在 awk 完成瀏覽動(dòng)作后打印輸出文本總數(shù)和結(jié)尾狀態(tài)標(biāo)識(shí).
使用$1,$3 表示參照第一個(gè)和第三個(gè)域,注意這里使用逗號(hào)做域分割,如果希望打印一個(gè)有 5 個(gè)域的記錄的所有域,可使用$0,意即所有域.
為打印一個(gè)域或所有域,使用 printf 命令,這是一個(gè) awk 動(dòng)作
模式:兩個(gè)特殊段 BEGIN 和 END
動(dòng)作:實(shí)際動(dòng)作大多在{}內(nèi)指明
輸出:
抽取域
命令:awk -F: '{print $1}' /etc/passwd
輸出:打印/etc/passwd 目錄下的所有用戶名
保存輸出
awk -F: ‘{print $1}’ /etc/passwd |tee user
使用 tee 命令,在輸出文件的同時(shí),輸出到屏幕
awk -F : ‘{print $1}’ /etc/passwd > user3
awk -F : ‘{print $0}’ /etc/passwd
打印單獨(dú)記錄
awk -F: ‘{print $1,$4}’ /etc/passwd
打印報(bào)告頭
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,打印他
精確匹配
使用符號(hào)==
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/)表示第四個(gè)字母是 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ù)個(gè)數(shù) |
ARGV |
命令行參數(shù)列表 |
ENV?|RON |
支持隊(duì)列中的系統(tǒng)環(huán)境變量的使用 |
FNR |
瀏覽文件的記錄數(shù) |
FS |
置頂分隔符,等價(jià)于-F |
NF |
瀏覽記錄的域的個(gè)數(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
文件長(zhǎng)度相加
ls -l | awk '/^[^d]/ {print $9"\t" $5}{tot+=$5}\
END {print "total kb:"tot}'
gsub(r,s) |
在整個(gè)$0中s替換r |
gsub(r,s,t) |
在整個(gè)t中s替換r |
index(s,t) |
返回s中字符串t的第一位置 |
length(s) |
返回s長(zhǎng)度 |
match(s,r) |
測(cè)試s中是否包含匹配r的字符串 |
split(s,a,fs) |
在fs上將s分成序列a |
sub(s,) |
用$0中最左邊也是最長(zhǎng)的字符串替代 |
subtr(s,p) |
返回字符串s中從p開始的后綴部分 |
substr(s,p,n) |
返回字符串s中從p開始長(zhǎng)度為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/passwd
wk -F : '$1=="root"{print length($1)"\t" $0}' /etc/passwd
match(在 ANCD 中查找 C 的位置)
awk 'BEGIN{print match("ANCD","C")}'
split 返回字符串?dāng)?shù)組元素個(gè)數(shù)
awk 'BEGIN{print split("123#456#789",array,"#")}'
sub 只能替換指定域的第一個(gè) 0
awk 'sub(/0/,2){print }' /etc/fstab
awk 'BEGIN{print substr("www.baidu.com",5,9)}'
#第五個(gè)子夫開始,取9個(gè)字符awk 'BEGIN{print substr("www.baidu.com",5)}'
#第五個(gè)位置開始,一直到最后
字符串屏蔽序列
符號(hào) | 含義 |
---|---|
\b | 退格符 |
\f | 走紙換頁(yè) |
\n | 新行 |
\r | 回車 |
\t | tab鍵(四個(gè)空格) |
\c | 任意其他特殊字符 |
\ddd | 八進(jìn)制 |
案例:
awk -F : '{print $1,"\b" $2,"\t" $3}' /etc/passwd
分析:print 和 printf 兩者效果不同
printf 修飾符
awk printf 格式
符號(hào) | 含義 |
---|---|
%c | ASCII 字符 |
%d | 整數(shù) |
%e | 科學(xué)計(jì)數(shù)法 |
%f | 浮點(diǎn)數(shù) |
%g | awk 決定使用哪種浮點(diǎn)數(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/passwd
awk -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 選項(xiàng)。
執(zhí)行時(shí),直接在 awk 腳本名后面加要處理的文件名作為參數(shù)即可。