awk實例操作學習記錄

awk是一種編程語言,用於在linux/unix下對文本和數據進行處理。數據可以來自標準輸入、一個或多個文件,或其它命令的輸出。它支持用戶自定義函數和動態正則表達式等先進功能,是linux/unix下的一個強大編程工具。
awk的處理文本和數據的方式是這樣的,它逐行掃描文件,從第一行到最後一行,尋找匹配的特定模式的行,並在這些行上進行你想要的操作。如果沒有指定處理動作,則把匹配的行顯示到標準輸出(屏幕),如果沒有指定模式,則所有被操作所指定的行都被處理。
例子:
一般語法格式
1.# awk '{ print }' /etc/passwd
或# awk '{ print $0 }' /etc/passwd
馬上顯示/etc/passwd的內容,其中$0變量表示整個當前行
2.# awk '{ print "william" }' /etc/passwd
或# awk '{ print "" }' /etc/passwd
第一條按照/etc/passwd文件中的行數顯示william,第二條則顯示空行。

字段
3.# awk -F: '{ print $1 }' /etc/passwd
或# awk -F: '{ print $1 $3 }' /etc/passwd
第一條打印輸入文件中每一行中出現的第一個字段,第二條則打印第一和第三字段。其中-F:表示指定“:”作爲字段分隔符。
4.# awk -F: '{ print $1 " " $3 }' /etc/passwd
# awk -F: '{ print "username: "$1 "\t\tuid: " $3 }' /etc/passwd
例3中輸出的結果兩個字段之間沒有空格,這第一條命令就是加空格,第二條則加了文本標籤。

外部腳本
5.# awk -f my.awk /etc/passwd
如果要運行外部的腳本加上-f選項即可,其中my.awk是腳本,/etc/passwd是要操作的文本。

BEGIN和END塊
6.BEGIN{
FS=":"        相當於命令行中的-F:
}
{ print $1 }
END{
print "william"
}
awk開始處理文件之前會執行BEGIN塊,awk處理文件之後會執行END塊。

表達式和塊
7.# awk '/root/ { print }' /etc/passwd    打印包含root的行
# awk '/^root/ { print }' /etc/passwd    打印以root開頭的行
# awk '/~root/ { print NR NF }' /etc/passwd    有以root結尾的行打印當前記錄數和當前記錄字段數
# awk '/^root|wang/ { print }' /etc/passwd    打印以root或wang開頭的行
# awk '/^[rw]/ { print }' /etc/passwd    打印以字母r或w開頭的行
# awk '$1 ~/[0-9]/ { print }' /etc/passwd    打印字段1中以數字結尾的行
# awk -F: '$4 ^/[0-9]/ { print }' /etc/passwd    打印字段4中以數字開頭的行
8.# awk -F: '$4==27 { print }' /etc/passwd    打印字段4等於27的行
# awk -F: '$4!=27 || $3>492 { print }' /etc/passwd    打印字段4不等於27或字段3大於492的行
# awk -F: '$4==27 || $3>42 { print $1+10 }' /etc/passwd    假如字段4等於27或者字段3大於42,打印$1+10的值,如果$1不是數字默認爲0。
# awk -F: '{print $4==27 ? "ok" : "err"}' /etc/passwd    字段4等於27打印ok,否則打印err
# awk '/^root/,/^bin/' /etc/passwd    打印以root開頭到以bin開頭的所有行,假如出現第二個以root開頭的行,則到下一個yibin開頭的行結束或到文件結尾。

條件語句
9.BEGIN{
FS=":"
}
{
if($3==27){
        if($4==27){
        print "love"
        }
}
else if($1 ~/root/) { print "one"}    //~是包含,^是不包含
else {
         print "others" " " $1}
}
END{
print "william"
}

變量
10.BEGIN   {x=0}
/^$/ {x=x+1}
END {print "There are "x" blank lines."}
計算空白行的數量
11.# awk -f my.awk x=8 ./test.c 
原來是5,加入x=8後,結果變成了13.另外BEGIN   {x=0}可以不要。
12.BEGIN   {x="0.01"}    //注意變成字符串了
/^$/ {x=x+1}
END {print "There are "x" blank lines."}
執行# awk -f my.awk  ./test.c 結果是5.01

字段分隔符
前面設置FS=":",當然也可以設置多個任意字符爲分隔符。
例如:
FS="\t+"    +號表示一個或多個
FS="root[0-9][0-9]"    表示root後面接兩個數字爲分隔符

記錄分隔符
NR 記錄號 NS 記錄分隔符 FS字段分隔符
比如通訊錄把名字 地址 電話號碼整理爲一個記錄。其中文本如下
wang
Hunan Chenzhou
123456

li
Guangzhou Zhuhai
654321
13.執行腳本爲:BEGIN {
    FS="\n"
    RS=""
}
{print $1 ","$2","$3}
輸出:
wang,Hunan Chenzhou,123456
li,Guangzhou Zhuhai,654321

14.執行腳本爲:BEGIN   {
FS="\n"
RS=""
OFS="-"    輸出字段間隔
ORS="\nnext:\n"    輸出記錄間隔
}
{print $1, $2, $3}
輸出:
wang-Hunan Chenzhou-123456
next:
li-Guangzhou Zhuhai-654321
next:

循環語句
15.BEGIN   {
FS="\n"
RS=""
OFS="-"
ORS=""
}
{
x=1
while(x<NF){
print $x "\t"    上面的OFS賦值將不起作用
x++
}
print $NF "\n"}
此外有do while,for,break,continue。

數組
16.
數組下標經常從1開始,而不是0
數組下標字符串化 例如:myarr["name"]="wang" 就算不是字符串也會被看成字符串。
17.delete myarr[1]     刪除數組元素1
18.if (wang in myarr) {print "ok"}     查看數組元素

字符串函數
string="Wo men shi ku bi de cheng xu yuan !"
print string[2]     會報錯!!
怎麼辦?
print length(string)    打印字符串長度
print index(string,"men")    查找men在字符串中的位置
print tolower(string)    轉換爲小寫
print toupper(string)    轉換爲大寫
mysbu=substr(string,startpos,maxlen)    在startpos開始截取maxlen這麼長的字符
print match(string,/men/),RSTART,RLENGTH    尋找匹配men的位子和長度
sbu(old,new,string) 替換一個
gsbu(old,new,string)    全部替換
num=split("1,2,3,4,5,6",mynum,",")    切開字符串,並將各部分放到整數下標的數組中

函數格式
function 函數名(參數)
{
    ……
}




發佈了61 篇原創文章 · 獲贊 10 · 訪問量 30萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章