awk 可以勝任幾乎所有的文本處理工作。
awk調(diào)用
調(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è)文件,并使阿瓦庫程序可執(zhí)行,然后用 awk
命令解釋器作為腳本的首行,以便通過鍵入腳本名成功來調(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)行瀏覽的文件名。模式和動(dòng)作
任何 awk
語句都是有模式和動(dòng)作組成。在一個(gè) awk
腳本中可能有很多語句,模式部分決定動(dòng)作語句何時(shí)觸發(fā)以及出發(fā)時(shí)間。處理即對數(shù)據(jù)進(jìn)行的操作。如果省略模式部分,動(dòng)作將時(shí)刻保持執(zhí)行狀態(tài)。模式可以是任何條件語句或符合語句或正則表達(dá)式。模式包括兩個(gè)特殊字段 BEGIN
和 END
。使用 BEGIN
語句設(shè)置計(jì)數(shù)和打印頭。BEGIN
語句使用在任何文本瀏覽動(dòng)作之前,之后文本瀏覽動(dòng)作一句輸入文本開始執(zhí)行。END
語句用來在 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)作。
模式和動(dòng)作
BEGIN
和 END
輸出:
抽取域
命令: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,打印他 awk -F:'{if($3==0) print}' /etc/passwd
awk -F:'{if($1!~/linuxone/) print}' /etc/passwd
精確不匹配!=awk -F:'{if($1!=/linuxone/) print}' /etc/passwd
awk -F :'{f($1~/^...t/) print}' /etc/passwd
分析:if($1~/^...t/) 表示第四個(gè)字母是 t '{if($1~/(squid|nagios)/) print}' /etc/passwd
awk '/^root/' /etc/passwd
分析:^root(行首包含 root) 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
文件長度相加
ls -l | awk '/^[^d]/ {print $9"\t"$5}{tot+=$5}\ END {print"total kb:"tot}'
內(nèi)置的字符串函數(shù)
gsub(r,s)
在整個(gè) $0 中 s 替換 r
gsub(r,s,t)
在整個(gè) 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/passwd wk -F :'$1=="root"{print length($1)"\t"$0}' /etc/passwd
awk 'BEGIN{print match("ANCD","C")}'
awk 'BEGIN{print split("123#456#789",array,"#")}'
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
走紙換頁
\n
新行
\r
回車
\t
tab 鍵 (四個(gè)空格)
\c
任意其他特殊字符
\ddd
八進(jìn)制
案例:
awk -F :'{print $1,"\b"$2,"\t"$3}' /etc/passwd
分析:print 和 printf 兩者效果不同
printf 修飾符
-
:左對齊width
:域的步長 0 表示 0 步長.prec
:最大字符串長度,或小數(shù)點(diǎn)右邊的位數(shù)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)制
字符串轉(zhuǎ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ù)即可。