最近在做一個作業(yè)茸歧,需要篩選文檔里面的內(nèi)容罗标。在網(wǎng)上谷歌到這個函數(shù)之后發(fā)現(xiàn)簡直不要太好用秋柄!介紹一下
首先获枝,awk好像不只是一個函數(shù),而是一種優(yōu)良的文本處理工具骇笔,Linux及Unix環(huán)境中現(xiàn)有的功能最強大的數(shù)據(jù)處理引擎之一(wiki)省店。我要說的其實是他的一個版本嚣崭,就是awk的GNU版本——gawk(其實也沒啥區(qū)別吧……)再多嘴一句,awk的執(zhí)行流程是懦傍,逐行掃描文件或者輸入雹舀,查找與命令行中所給定內(nèi)容相匹配的模式。如果發(fā)現(xiàn)匹配內(nèi)容粗俱,則進行下一個編程步驟说榆。如果找不到匹配內(nèi)容,則繼續(xù)處理下一行寸认。
awk命令由一系列‘模式——動作’對來組成签财, 既‘pattern {action}’。無pattern默認匹配全部的記錄废麻;而無action則是打印原始記錄荠卷。除了簡單的AWK表達式之外,pattern可以是BEGIN或END烛愧;這兩種條件對應的action分別是讀取所有的記錄之前和之后油宜。同時,如pattern1, pattern2的條件表示符合條件pattern1和pattern2的記錄及其之間的部分怜姿。
awk的內(nèi)建變量和運算符
1慎冤,變量
變 量描述
$n當前記錄的第n個字段,字段間由 FS分隔沧卢。
$0完整的輸入記錄蚁堤。
ARGC命 令行參數(shù)的數(shù)目。
ARGIND命令行中當前文件的位置(從0開始算)但狭。
ARGV包 含命令行參數(shù)的數(shù)組披诗。
CONVFMT數(shù)字轉(zhuǎn)換格式(默認值為%.6g)
ENVIRON環(huán) 境變量關聯(lián)數(shù)組。
ERRNO最后一個系統(tǒng)錯誤的描述立磁。
FIELDWIDTHS字 段寬度列表(用空格鍵分隔)呈队。
FILENAME當前文件名。
FNR同 NR唱歧,但相對于當前文件宪摧。
FS字段分隔符(默認是任何空格)。
IGNORECASE如 果為真颅崩,則進行忽略大小寫的匹配几于。
NF當前記錄中的字段數(shù)。
NR當 前記錄數(shù)沿后。
OFMT數(shù)字的輸出格式(默認值是%.6g)沿彭。
OFS輸 出字段分隔符(默認值是一個空格)。
ORS輸出記錄分隔符(默認值是一個換行符)尖滚。
RLENGTH由 match函數(shù)所匹配的字符串的長度膝蜈。
RS記錄分隔符(默認是一個換行符)锅移。
RSTART由 match函數(shù)所匹配的字符串的第一個位置。
SUBSEP數(shù)組下標分隔符(默認值是\034)饱搏。
2非剃,運算符
運算符描述
=? +=? -=? *=? /=? %=? ^=? **=賦值
?:C條件表達式
||邏 輯或
&&邏輯與
~? ~!匹 配正則表達式和不匹配正則表達式
<? <=? >? >=? !=? ==關 系運算符
空格連接
+? -加,減
*? /? &乘推沸,除與求余
+? -? !一元加备绽,減和邏輯非
^? ***求冪
++? --增加或減少,作為前綴或后綴
$字 段引用
in數(shù)組成員
四鬓催,awk的正則
匹配符描述
\Y匹配一個單詞開頭或者末尾的空字符串
\B匹配單詞內(nèi)的空字符串
\<匹配一個單詞的開頭的空字符串肺素,錨定開始
\>匹配一個單詞的末尾的空字符串,錨定末尾
\W匹配一個非字母數(shù)字組成的單詞
\w匹配一個字母數(shù)字組成的單詞
\'匹配字符串末尾的一個空字符串
\‘匹配字符串開頭的一個空字符串
五宇驾,awk的函數(shù)
1倍靡,字符串函數(shù)
函數(shù)名描述
sub匹配記錄中最大、最靠左邊的子字符串的正則表達式课舍,并用替換字符串替換這些字符串塌西。如果沒有指定目標字符串就默認使用整個記錄。替換只發(fā)生在第一次匹配的 時候
gsub整個文檔中進行匹配
index返回子字符串第一次被匹配的位置筝尾,偏移量從位置1開始
substr返回從位置1開始的子字符串捡需,如果指定長度超過實際長度,就返回整個字符串
split可按給定的分隔符把字符串分割為一個數(shù)組筹淫。如果分隔符沒提供站辉,則按當前FS值進行分割
length返回記錄的字符數(shù)
match返回在字符串中正則表達式位置的索引,如果找不到指定的正則表達式則返回0损姜。match函數(shù)會設置內(nèi)建變量RSTART為字符串中子字符串的開始位 置饰剥,RLENGTH為到子字符串末尾的字符個數(shù)。substr可利于這些變量來截取字符串
toupper和tolower可用于字符串大小間的轉(zhuǎn)換摧阅,該功能只在gawk中有效
2捐川,數(shù)學函數(shù)
函數(shù)名返回值
atan2(x,y)y,x 范圍內(nèi)的余切
cos(x)余弦函數(shù)
exp(x)求 冪
int(x)取整
log(x)自然對 數(shù)
rand()隨機數(shù)
sin(x)正弦
sqrt(x)平 方根
srand(x)x是rand()函數(shù)的種子
int(x)取 整,過程沒有舍入
rand()產(chǎn)生一個大于等于0而小于1的隨機數(shù)
1逸尖,測試文件test
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false
mail:x:8:12:mail:/var/spool/mail:/bin/false
ftp:x:14:11:ftp:/home/ftp:/bin/false
&nobody:$:99:99:nobody:/:/bin/false
zhangy:x:1000:100:,,,:/home/zhangy:/bin/bash
http:x:33:33::/srv/http:/bin/false
dbus:x:81:81:System message bus:/:/bin/false
hal:x:82:82:HAL daemon:/:/bin/false
mysql:x:89:89::/var/lib/mysql:/bin/false
aaa:x:1001:1001::/home/aaa:/bin/bash
ba:x:1002:1002::/home/zhangy:/bin/bash
test:x:1003:1003::/home/test:/bin/bash
@zhangying:*:1004:1004::/home/test:/bin/bash
policykit:x:102:1005:Po
例1:
cat test | awk -F: '{\
if ($1 == "root"){\
print $1;\
}else if($1 == "bin"){\
print $2;\
}else{\
print $3;\
} \
}'
例2:
awk '{\
for(i=0;i
if ($i ~/^root/){\
print $i;\
}else if($i ~/zhangy/){\
print $i;continue;\
}else if($i ~/mysql/){\
print $i;next;\
}else if($i ~/^test/){\
print $i;break;\
} \
}\
}' test
例3:
tail test | awk 'BEGIN{while(getline d){ split(d,test);for(i in test){\
print test[i]\
}}}'
例4:
ls -al /home/zhangy/mytest | awk 'BEGIN{while(getline d){ split(d,test);\
print test[9] ;}
}'
例5:
echo "32:34" |awk -F: '{print "max = ",max($1,$2)}\
function max(one,two){
if(one > two){
return one;
}else{
return two;
}
}
'
例6:
#awk 'BEGIN{print "what is your name"; getline name < "/dev/tty"}$1 ~name{print
#"found name on line" NR}END{print "see you" name}' test
#awk '{sub(/daemon/,"tankzhang");print}' test
#awk '{{sub(/zhangy/,"tankzhang");$1};print}' test
#awk '{{gsub(/zhangy/,"tankzhang");$1};print}' test
#awk -F: '{print index("zhangy",$1)}' test
#awk -F: '{print substr($1,1,2)}' test
awk -F: '{mat=match($1,/^[a-zA-Z]+$/);print mat,RSTART,RLENGTH}' test
例7:
cat test |awk -F: '\
NF != 7{\
printf("line %d,does not have 7 fields:%s\n",NR,$0)}\
$1 !~ /^[A-Za-z0-9]/{printf("line %d,non alpha and numeric user id:%s: %s\n",NR,$1,$0)}\
$2 == "*" {printf("lind %d,no password:%s\n",NR,$0)}'