Linux三劍客:awk

awk簡介

 awk程序設計語言 允許您創建簡短的程序,這些程序讀取輸入文件、爲數據排序、處理數據、對輸入執行計算以及生成報表等功能。awk 借鑑了某些語言的一些精華,如 C 語言等。在 linux 系統日常處理工作中,發揮很重要的作用,掌握了 awk將會使你的工作變的so easy。

awk語言的最基本功能是在文件或者字符串中基於指定規則瀏覽和抽取信息,awk抽取信息後,才能進行其他文本操作。完整的awk腳本通常用來格式化文本文件中的信息。

通常,awk是以文件的一行爲處理單位的。awk每接收文件的一行,然後執行相應的命令,來處理文本。

語法格式

awk [options] 'script' var=value file(s) 
awk [options] -f scriptfile var=value file(s) 

常用命令選項

  • -F fs fs 指定輸入分隔符,fs可以時字符串或正則表達式

  • -v var=value 賦值一個用戶定義變量,將外部變量傳遞給awk

  • -f scriptfile 從腳本文件中讀取awk命令

awk腳本

awk腳本是由模式和操作組成的。

模式與操作

模式

模式可以是以下任意一種:

  • 正則表達式:使用通配符的擴展集

  • 關係表達式:使用運算符進行操作,可以是字符串或數字的比較測試

  • 模式匹配表達式:用運算符(匹配)和~!不匹配

  • BEGIN 語句塊, pattern語句塊, END語句塊

操作

操作由一個或多個命令、函數、表達式組成,之間由換行符或分號隔開,並位於大刮號內,主要部分是:變量或數組賦值、輸出命令、內置函數、控制流語句。

awk腳本基本格式

awk 'BEGIN{ commands } pattern{ commands } END{ commands }' file 

一個awk腳本通常由BEGIN, 通用語句塊,END語句塊組成,三部分都是可選的。 腳本通常是被單引號或雙引號包住

awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename  

awk執行過程分析

  • 第一步: 執行BEGIN { commands } pattern 語句塊中的語句

    BEGIN語句塊:在awk開始從輸入輸出流中讀取行之前執行,在BEGIN語句塊中執行如變量初始化,打印輸出表頭等操作。

  • 第二步:從文件或標準輸入中讀取一行,然後執行pattern{ commands }語句塊。它逐行掃描文件,從第一行到最後一行重複這個過程,直到全部文件都被讀取完畢。

    pattern語句塊:pattern語句塊中的通用命令是最重要的部分,它也是可選的。如果沒有提供pattern語句塊,則默認執行{ print },即打印每一個讀取到的行。{ }類似一個循環體,會對文件中的每一行進行迭代,通常將變量初始化語句放在BEGIN語句塊中,將打印結果等語句放在END語句塊中。

  • 第三步:當讀至輸入流末尾時,執行END { command }語句塊

    END語句塊:在awk從輸入流中讀取完所有的行之後即被執行,比如打印所有行的分析結果這類信息彙總都是在END語句塊中完成,它也是一個可選語句塊。

    AWK內置變量

  • $n : 當前記錄的第n個字段,比如n爲1表示第一個字段,n爲2表示第二個字段。

  • $0 : 這個變量包含執行過程中當前行的文本內容。

  • FIELDWIDTHS : 字段寬度列表(用空格鍵分隔)。

  • FILENAME : 當前輸入文件的名。

  • NR : 表示記錄數,在執行過程中對應於當前的行號

  • FNR : 同NR :,但相對於當前文件。

  • FS : 字段分隔符(默認是任何空格)。

  • IGNORECASE : 如果爲真,則進行忽略大小寫的匹配。

  • NF : 表示字段數,在執行過程中對應於當前的字段數。 print $NF答應一行中最後一個字段

將外部變量值傳遞給awk

  • 藉助 -v 選項,可以將來自外部值(非stdin)傳遞給awk

    VAR=10000
    echo | awk -v VARIABLE=$VAR '{ print VARIABLE }'

  • 定義內部變量接收外部變量

    var1="aaa"
    var2="bbb"
    echo | awk '{ print v1,v2 }' v1=$var1 v2=$var2

  • 使用"'把shell變量包起來,即"'$var'";注意是“雙引號+單引號+shell變量+單引號+雙引號”的格式

    var="abc"

    awk 'BEGIN{print "'$var'"}'

  • 使用"'"把shell變量包起來,即"'"$var"'";注意是“雙引號+單引號+雙引號+shell變量+雙引號+單引號+雙引號”的格式。

    如果變量的值中包含空格,爲了shell不把空格作爲分隔符,則應使用這種方法。

    var="this a test"

    awk 'BEGIN{print "'"$var"'"}'

  • export變量,然後在awk中使用ENVIRON["var"]形式獲取環境變量的值

    var="this a test"; export var;

    awk 'BEGIN{print ENVIRON["var"]}'  

    awk運算

  • 算術運算:(+,-,*,/,&,!,……,++,--)

    所有用作算術運算符進行操作時,操作數自動轉爲數值,所有非數值都變爲0

  • 賦值運算:(=, +=, -=,*=,/=,%=,……=,**=)

  • 邏輯運算符: (||, &&)

  • 關係運算符:(<, <=, >,>=,!=, ==)

  • 正則運算符:(~,~!)(匹配正則表達式,與不匹配正則表達式)

    awk 'BEGIN{a="100testa";if(a ~ /^100*/){print "ok";}}'
    ok

    next 語句

    awk中next語句使用:在循環逐行匹配,如果遇到next,就會跳過當前行,直接忽略下面語句。而進行下一行匹配。net語句一般用於多行合併:

    awk 'NR%2==1{next}{print NR,$0;}' text.txt
    說明: 當記錄行號除以2餘1,就跳過當前行。下面的print NR,$0也不會執行。下一行開始,程序有開始判斷NR%2值。這個時候記錄行號是:2 ,就會執行下面語句塊:print NR,$0

    文件操作

  • 打開文件 open("filename")

  • 關閉文件 close("filename")

  • 輸出到文件 重定向到文件,如echo | awk '{printf("hello word!n") > "datafile"}'

     

循環結構

for循環

for(變量 in 數組)  
{語句} 
 
for(變量;條件;表達式) 
{語句} 

while循環

while(表達式) 
    {語句} 

do...while循環

do  
{語句} while(條件) 

其他相關語句

  • break:退出程序循環

  • continue: 進入下一次循環

  • next:讀取下一個輸入行

  • exit:退出主輸入循環,進入END,若沒有END或END中有exit語句,則退出腳本。

數組

在awk中數組叫做關聯數組(associative arrays)。awk 中的數組不必提前聲明,也不必聲明大小。數組元素用0或空字符串來初始化,這根據上下文而定。

awk 'BEGIN{ 
        Array[1]="lee"  
        Array[2]="gwin" 
        Array["first"]="www"  
        Array["last"]="name"  
        Array["birth"]="1992" 
         
        info = "it is a test"; 
        lens = split(info,tA," "); 
        for(item in tA){
            print tA[item];
          } 
        for(i=1;i<=lens;i++){
            print tA[i];
          } 
        print length(tA[lens]); 
        } 
        { 
        print "item in array"; 
        for(item in Array) {
            print Array[item]
        }; 
        print "print in i++"; 
        for(i=1;i<=length(Array);i++) {
            print Array[i]};   
        }' 
  • 獲取數組長度

awk 'BEGIN{ 
        info="it is a test"; 
        lens=split(info,tA," ");    #使用split函數獲取數組長度 
        print length(tA),lens;      #使用length函數獲取數組長度(版本有要求) 
        }' 
  • 輸出數組內容

    • 有序輸出 for...in

      因爲數組時關聯數組,默認是無序的

    • 無序輸出 for(i=1;i<l=ens;i++)

      數組下標從1開始

  • 判斷鍵值是否存在
#判定方法:使用 if ( key in array) 判斷數組中是否包含 鍵值 
awk 'BEGIN{ 
        tB["a"]="a1"; 
        tB["b"]="b1"; 
        if( "c" in tB){ 
            print "ok"; 
        }; 
        for(k in tB){ 
            print k,tB[k]; 
        }}' 

 

  • 刪除鍵值
    delete array[key]可以刪除,對應數組key的,序列值。

    awk 'BEGIN{ 
            tB["a"]="a1"; 
            tB["b"]="b1"; 
            delete tB["a"]; 
            for(k in tB){ 
                print k,tB[k]; 
            }}' 

    內置函數

    算術函數

    格式 描述
    atan2( y, x ) 返回 y/x 的反正切。
    cos( x ) 返回 x 的餘弦;x 是弧度。
    sin( x ) 返回 x 的正弦;x 是弧度。
    exp( x ) 返回 x 冪函數。
    log( x ) 返回 x 的自然對數。
    sqrt( x ) 返回 x 平方根。
    int( x ) 返回 x 的截斷至整數的值。
    rand( ) 返回任意數字 n,其中 0 <= n < 1。
    srand( [expr] ) 將 rand 函數的種子值設置爲 Expr 參數的值,或如果省略 Expr 參數則使用某天的時間。返回先前的種子值。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章