1. 程式人生 > >AWK再次認識--內建的引數,以及編寫指令碼

AWK再次認識--內建的引數,以及編寫指令碼

〇、前言

    意見反饋,請mailto:[email protected]

一、AWK簡介

         AWK名字來源於三位創造者Aho、Weinberger和Kernighan統稱。

         AWK擅長處理文字資料。

二、AWK的呼叫方式

         awk [-Ffs] [-v var=value] [program | -f progfile ...] [file ...]

    1、命令列方式

         例如:

awk '{print $1}' file

ps -ef|grep program|awk '{print $2}'

         2、檔案方式

         例如:

awk -f progfile file

         3、檔案直譯器方式

         AWK指令碼檔案開頭需要註明呼叫方式,典型寫法為:

         #!/bin/awk -f

    注意-f後面有空格。

         指令碼檔案需要有執行許可權,如果沒有需要使用chmod +x progfile賦權。

         例如:

progfile file

三、AWK引數

         -F  指定域分隔符,例如:-F "|",即以|作為域分隔符,預設分隔符為一個或多個空格或TAB,即"[[:space:]][[:space:]]*"。

         -v  定義變數,從shell給awk傳遞變數,如-vDATE=$DATE,即將shell中$DATE變數值傳遞給awk變數DATE。

         -f  指定指令碼檔案,例如-f progfile。

四、AWK內建變數

         FS      域分隔符

         NF      域個數

         NR      行數

         FNR     同上

         FILENAME    處理的檔名,當輸入為管道時,FILENAME為空。

         RS      行分隔符

         OFS     輸出域分隔符

         ORS     輸出行分隔符

         OFMT        數字輸出格式

         CONVFMT     數字內部轉換格式

         SUBSEP      多維陣列索引分隔符

         ARGC        輸入引數個數

         ARGV        輸入引數陣列

         ENVIRON     環境變數陣列

         RSTART      match()函式正則匹配到字串開始位置

         RLENGTH     match()函式正則匹配到字串的長度

五、AWK內建函式

         blength[([s])]          計算字串長度(byte為單位)

    length[([s])]           計算字串長度(character為單位)

    rand()              生成隨機數

         srand([expr])           設定rand() seed

    int(x)              字串轉換為整型

         substr(s, m [, n])      取子字串

         index(s, t)         在字串s中定位t字串首次出現的位置

         match(s, ere)           在字串s中匹配正則ere,match修改RSTART、RLENGTH變數。

         split(s, a[, fs])       將字串分割到陣列中

         sub(ere, repl [, in])   字串替換

         gsub                同上

         sprintf(fmt, expr, ...) 拼字串

         system(cmd)         在shell中執行cmd。

         toupper(s)          字串轉換為大寫

         tolower(s)          字串轉換為小寫

六、AWK流程控制

         if(expression) statement [ else statement ]

    while(expression) statement

    for(expression;expression;expression) statement

    for(var in array) statement

    do statement while(expression)

    break

    continue

    {[statement  ...]}

    expression          # commonly  var = expression

    print [expression-list] [ > expression]

    printf format [, expression-list] [ > expression]

    return [expression]

    next                # skip remaining patterns on this input line.

    delete array [expression]   # delete an array element.

    exit [expression]   # exit immediately; status is expression.

七、AWK簡單應用範例

         AWK指令碼分為三部分BEGIN段,處理段,END段。其中BEGIN段在第一行讀取之前執行,END段在最後一行處理後執行。

1、內容過濾,同"grep tag file"。

#前兩個語句為正則匹配

awk '/tag/ {print}' file

awk '{if($0 ~/tag/) print}' file

awk '{if(index($0, "tag") > 0) print}' file

2、取特定列,同"cut –f1 –f3 –f5 file"。

#輸出檔案第1、3、5列

awk '{print $1, $3, $5}' file

3、對檔案內容進行剔重,類似"sort -u file",但未排序。

#如果當前行未存在於rec HASH表中,則記錄此行資料,並輸出

awk '{if(!($0 in rec)) {rec[$0]=1; print $0;}}' file

         AWK中陣列有兩種用法普通陣列和HASH陣列,此處為HASH陣列。

4、僅輸出資料

#輸出100行資料

awk ‘BEGIN {for(i = 0; i < 100; i++) printf("this is %d\n", i);}’

可見,如果指令碼中只有BEGIN段,可以沒有輸入。

5、統計資料

#對第一列和第二列資料進行彙總,最終輸出

awk ‘{a+=$1; b+=$2}END{printf("a=%d\n,b=%d\n", a, b);}’ file

八、AWK高階應用範例

1、 分組功能,類似Group by功能

#使用第一列作為分組列,第二列為聚合列,即select col1, sum(col2) from file group by col1

awk ‘{tot[$1] += $2}END{for(i in tot) printf("%s %d\n", i, tot[i]);}’ file

#比上個例子增加一個類似having的用法

awk ‘{tot[$1] += $2}END{for(i in tot) if(tot[i] > 10) printf("%s %d\n", i, tot[i]);}’ file

#使用第一列作為分組列,第二列、第三列為聚合列

awk ‘{tot1[$1] += $2; tot2[$1] += $3;}END{for(i in tot1) printf("%s %d %d\n", i, tot1[i], tot2[i]);}’ file

#多維陣列例子,可將多個欄位作為分組列,AWK使用一維陣列模擬多維陣列,使用\034作為分隔符

awk ‘{tot1[$1, $2] += $3; tot2[$1, $2] += $4;}END{for(i in tot1) printf("%s %d %d\n", i, tot1[i], tot2[i]);}’ file 

2、 檔案操作

#將兩個檔案根據filename1的第一列和filename2的第二列進行關聯

BEGIN {

        #讀取filename1檔案內容

        while((getline < "filename1") != NULL)

        {

                rel[$1] = 1;

                rec1[$1] = $2;

        }

        while((getline < "filename2") != NULL)

        {

                rel[$2] = 1;

                rec2[$2] = $3;

        }

        for(i in rel)

        {

                printf("%s %s %s\n", i, rec1[i], rec2[i]);

        }

}

#將檔案按照欄位進行拆分

{

        print $0 >> "split/" substr($1,1,7);

}

3、 從SHELL向AWK傳遞變數

awk  -vAWK_DATE=$DATE 'BEGIN {print AWK_DATE}'

4、 在AWK內部讀取shell命令輸出

#讀取ls命令輸出,在AWK中列印輸出

BEGIN {

        while("ls"|getline)

        {

                print $0;

        }

}

#讀取date輸出

BEGIN {

        "date" | getline;

        print $0;

        "date +%Y" | getline v_year;

        print v_year;

}

5、 將AWK輸出通過管道傳遞給SHELL命令

#將列印資訊輸出給sort進行排序

BEGIN {

        for(i = 0; i < 100; i++)

        {

                printf("%03d\n", 100 - i) | "sort";

        }

}

6、 正則表示式簡單例子

#演示正則表示式的使用方法

BEGIN {

        str1 = "[email protected]";

        str2 = "[email protected]";

        str3 = "&^%[email protected]";

        str4 = "[email protected]";

        match(str1, "[a-zA-Z][a-zA-Z0-9.]*@[a-zA-Z0-9][a-zA-Z0-9.]*.[a-zA-Z]*[a-zA-Z]");

        if(RSTART > 0)

                printf("%s\n", substr(str1, RSTART, RLENGTH));

        else

                printf("[%s] not match\n", str1);

        match(str2, "[a-zA-Z][a-zA-Z0-9.]*@[a-zA-Z0-9][a-zA-Z0-9.]*.[a-zA-Z]*[a-zA-Z]");

        if(RSTART > 0)

                printf("%s\n", substr(str2, RSTART, RLENGTH));

        else

                printf("[%s] not match\n", str2);

        match(str3, "[a-zA-Z][a-zA-Z0-9.]*@[a-zA-Z0-9][a-zA-Z0-9.]*.[a-zA-Z]*[a-zA-Z]");

        if(RSTART > 0)

                printf("%s\n", substr(str3, RSTART, RLENGTH));

        else

                printf("[%s] not match\n", str3);

        match(str4, "[a-zA-Z][a-zA-Z0-9.]*@[a-zA-Z0-9][a-zA-Z0-9.]*.[a-zA-Z]*[a-zA-Z]");

        if(RSTART > 0)

                printf("%s\n", substr(str4, RSTART, RLENGTH));

        else

                printf("[%s] not match\n", str4);

}

7、自定義函式

function my_plus(a, b)

{

        return a + b;

}

BEGIN {

        printf("%d\n", my_plus(123, 321));

}

九、一些應用範例

         1、驗證話單正確性的一個指令碼

/^vc/ {

        #取話單中各個變數

        call_type = substr($0,3,2);

        call_duration = int(substr($0,95,6));

        roam_type = substr($0,210,1);

        fee_type = substr($0,211,1);

        dial_type = substr($0,212,3);

        chat_type = substr($0,215,3);

        cfee = int(substr($0,218,9));

        lfee = int(substr($0,236,9));

        #如果為國際漫遊,不分析,跳過

        if(roam_type > 4)

        {

                next;

        }

        if(call_type == "01")

        {

                if(substr(dial_type,1,1) != "0")

                {

                        if(lfee > 0)

                        {

                                printf("%s:LFEE_01\n", $0);

                        }

                        next;

                }

                if(roam_type != "0")

                {

                        if(fee_type == "0" || fee_type == "2" || fee_type == "3")

                        {

                                if(lfee > 0)

                                {

                                        printf("%s:LFEE_ERR02\n", $0)

                                }

                        }

                        else

                        {

                                if(cfee > 0)

                                {

                                        printf("%s:CFEE_ERR01\n", $0);

                                }

                        }

                }

                else

                {

                        if(fee_type != "0")

                        {

                                if(cfee > 0)

                                {

                                        printf("%s:CFEE_ERR02\n", $0);

                                }

                        }

                }

        }

        if(call_type == "02")

        {

                if(lfee > 0)

                {

                        printf("%s:LFEE_ERR03\n", $0);

                }

        }

}

         2、一個模擬求取批價標批費率計劃的例子

function my_match(str, pat)

{

#for debug

#printf("str==>|%s|,pat==>|%s|\n", str, pat);

        if(pat == "*")

                return 1;

        n = split(pat, arr, ",");

        for(z = 1; z <= n; z++)

        {

                gsub("\?", "[a-zA-Z0-9]", arr[z]);

#for debug

#printf("str==|%s|,arr==>|%s|\n", str, arr[z]);

                match(str, arr[z]);

                if(RSTART > 0)

                {

                        return 1;

                }

        }

        return 0;

}

BEGIN {

        dial_cnt = 0;

        while((getline < "dial.lst") != NULL)

        {

                dial[dial_cnt] = $1;

                dial_cnt++;

        }

        chat_cnt = 0;

        while((getline < "chat.lst") != NULL)

        {

                chat[chat_cnt] = $1;

                chat_cnt++;

        }

        cfg_cnt = 0;

        while((getline < "plan.lst") != NULL)

        {

                cfg_dial[cfg_cnt] = $1;

                cfg_chat[cfg_cnt] = $2;

                cfg_item[cfg_cnt] = $3;

                cfg_plan[cfg_cnt] = $4;

                cfg_cnt++;

        }

        for(d = 0; d < dial_cnt; d++)

        {

                for(c = 0; c < chat_cnt; c++)

                {

                        printf("%s %s|", dial[d], chat[c]);

                        out_cnt = 0;

                        for(i = 0; i < cfg_cnt; i++)

                        {

#for debug

#printf("\n<%d,%d,%d>test match==>|<%s, %s>; <%s, %s>|\n", d, c, i, dial[d], cfg_dial[i], chat[c], cfg_chat[i]);

                                if(my_match(dial[d], cfg_dial[i]) == 1 && my_match(chat[c], cfg_chat[i]) == 1)

                                {

                                        if(out_cnt == 0)

                                        {

                                                printf("%s %s %s %s\n", cfg_item[i], cfg_plan[i], cfg_dial[i], cfg_chat[i]);

                                        }

                                        else

                                        {

                                                printf("%s %s|%s %s %s %s\n", dial[d], chat[c], cfg_item[i], cfg_plan[i], cfg_dial[i], cfg_chat[i]);

                                        }

                                        out_cnt++;

                                }

                        }

                        if(out_cnt == 0)

                        {

                                printf("NULL\n");

                        }

                }

        }

}

相關推薦

AWK再次認識--引數以及編寫指令碼

〇、前言     意見反饋,請mailto:[email protected]。 一、AWK簡介          AWK名字來源於三位創造者Aho、Weinberger和Kernighan統稱。          AWK擅長處理文字資料。 二、AWK的呼叫方式          awk [-

Windows7搜尋同時搜尋檔名以及檔案裡面的內容

  操作方法:   1、在任意目錄中,按 ALT 鍵,會出現選單,選擇 “工具” 中的“資料夾選項”。在開啟的對話方塊中,點選“搜尋”標籤。再選擇“始終搜尋檔名和內容”。   2、這時再在資料夾的搜尋框中,輸入想要搜尋的內容就可以找到相應的檔案了。   但是,關鍵是這個但是,這時候只能搜尋出來文字檔案

python中的面向物件(簡單類的建立以及方法私有屬性和私有方法的使用)

一、什麼面向物件和麵向過程? 面向物件:--誰來做? 相比較函式,面向物件是更大的封裝,根據職責在一個物件中封裝多個方法 1.在完成某一個需求前,首先確定職責--要做的事(方法) 2.根據職責確定不同的物件,在物件內部封裝不同的方法(多個) 3.最後完成程式碼

HTML中的函式使用基礎(函式定義函式呼叫函式引數函式返回值巢狀函式遞迴函式變數作用域函式其他定義函式的方法)

HTML中的函式使用基礎 函式實質上是一個類似於單獨的邏輯單元的JavaScript程式碼,使用函式可以使程式碼更為簡潔,提供重用性,在JavaScript中,大約有95以上的程式碼是包含在函式中的,由此可見,函式在JavaScript中地位相當重要。 1、函式定義 在

python(day16)函式匿名函式

# add = lambda x,y:x+y # print(add(1,2)) # dic={'k1':10,'k2':100,'k3':30} # def func(key): # return dic[key] # print(max(dic,key=func)) #根據返回值判斷最

python函式這一波看完後又可以少些很多程式碼了 python函式大全

python內建函式大全   python內建函式 最近一直在看python的document,打算在基礎方面重點看一下python的keyword、Build-in Function、Build-in Constants、Bui

Action 與 Func是.NET類庫中增加的委託以便更加簡潔方便的使用委託。

Action 與 Func是.NET類庫中增加的內建委託,以便更加簡潔方便的使用委託。 最初使用委託時,均需要先定義委託型別,然後定義一個符合委託型別簽名的函式, 在呼叫前,需宣告並建立委託物件,將指定函式與委託進行關聯。 如例1: public delegate int Math(

切面的用法獲取切點的引數以及返回值

監聽到了impl下面的所有的方法     ps:注意   由@Before註解定義的方法會在 execution() 表示式內的方法被呼叫之前執行 由@After註解定義的方法會在 execution()表示式內的方法被呼叫

拉丁方陣(問題渴望求解!)

拉丁方陣,或稱為拉丁方,是一種特殊的Ñ階方陣。如果用1開始的Ñ個連續正整數排成N×N的方陣,且每一行和每一列沒有重複的數,就稱其為一個ñ階拉丁方陣。因為這樣的方陣最早填充的是拉丁字母,因此得名拉丁方陣。 例如,5階拉丁方陣: 有個問題不太清楚: 就是我如果是多測試用例的話利用指標返

js中的物件宿主物件和自定義物件

JS中,可以將物件分為“內建物件”、“宿主物件”和“自定義物件”三種。 1,內建物件 js中的內建物件包括Array、Boolean、Date、Function、Global、Math、Number、Object、RegExp、String以及各種錯誤類物件,包括Erro

Linux---python中的封裝(方法初始化方法)繼承

面向物件中:哪一個物件呼叫的方法,self就是哪一個物件的引用 在類封裝的方法內部,self就表示當前呼叫方法的物件自己 呼叫方法時,程式設計師不需要傳遞self引數(但是定義的時候,第一個引數必須是self) 在方法內部:可以通過self.訪問物件的屬性 在方法內部:

vue問題記錄(二):cookie實現三天免登陸以及記住使用者名稱密碼等

首先,我們是要在自己的專案目錄下面建立一個資料夾,如下圖 ,然後就在我標記的地方,寫關於cookie的方法,獲取cookie,設定,清除等,如下圖 程式碼如下,方便拷貝 //獲取cookie、 export functio

Linux程式設計 10 (shell外部命令與命令alias type命令)

一.  內部命令   Linux命令有內部命令(內建命令)和外部命令之分,內部命令和外部命令功能基本相同,但也有些細微差別。內部命令不需要使用子程序來執行,它們已經和shell編譯成一體,作為shell工具的組成部分存在。不需要藉助外部程式檔案來執行。它們是一些比較簡單的linux系統命令,如exit,his

CS5026E_CS5028EMOS600KHz,8A高效率升壓DC-DC轉換器

 Step-Up Converter 升壓DC-DC CS5026E 內建MOS,600KHz,8A高效率升壓DC-DC轉換器 CS8677 差分輸入,2x25W/4Ω 工作電壓範圍:6.5~18.5V,D類 CS8655 差分輸入,2x10W/4

awk執行的三種方式以及awk以shell指令碼檔案形式執行的注意事項

awk執行有三種形式: 1.直接以命令列來執行,如圖: 2.以awk指令碼檔案來執行 需要加-f選項。 3.以shell指令碼的形式來執行         以shell指令碼形式執行時,行首的#!/bin/bash 需變換為#!/bin/awk(awk所在的路徑

CSS 塊級元素block 元素 inline以及塊級元素inline-block

block元素(div、p、h1~h6、ul、ol、dl、li、dd、table、hr、blockquote、address、table、menu、pre,HTML5新增的header、section、aside、footer等) 從瀏覽器的顯示結果可以看出,塊級元素新開啟一行(即

PC微信瀏覽器history.go(-1)進入變空白問題

問題:電腦版微信瀏覽器中,history.length不會因為關閉瀏覽器而消失,所以在執行history.go(-1)時,微信瀏覽器會判定為上一個頁面存在,執行跳轉。但當在微信中點選連結直接進入目標頁面時,實際上當前瀏覽器中是不存在上一個頁面的,導致倒退變成空白。 解決方法1:可以直接使用win

函式匿名函式

一堆內建函式exec 沒有返回值eval 有返回值compile 編譯程式碼sorted(iterable, key=function排序規則, reverse=翻轉)map(function, iterable)filter(function, iterable)匿名函式 : lambda 引數: 返

day 12 函式裝飾器遞迴函式

內建函式 內建函式:python給咱們提供了一些他認為你會經常用到的函式,68種      內建函式     abs() dict() help() m

利用python函式快速統計單詞在文字中出現的次數

python中包含許多標準程式設計資料結構,如list(列表),tuple(元組)、dict(字典)和set(),如果現有的資料型別不能滿足需求,可以派生某個內建型別進行定製,或者使用collections中定義的某個抽象基類作為起點構建一個新的容器型別。 c