awk

awk

  awk是一種編程語言,對文本和數據進行處理
  數據來自標準輸入、一個或多個文件、或其它命令的輸出、用戶自定義函數和動態正則表達式等
  在命令行中或作爲腳本內建的功能,比如數組、函數等

語法形式

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

常用命令選項

 -F fs            fs指定輸入分隔符,fs可以是字符串或正則表達式,如-F:
 -v var=value      賦值一個用戶定義變量,將外部變量傳遞給awk
 -f scripfile     從腳本文件中讀取awk命令
 -m [fr] val      對val值設置內在限制
                  (-mf選項限制分配給val的最大塊數目;-mr選項限制記錄的最大數目)

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

/正則表達式/:使用通配符的擴展集
關係表達式:使用運算符進行操作,可以是字符串或數字的比較測試
模式匹配表達式:用運算符~(匹配)和~!(不匹配)
BEGIN語句塊、pattern語句塊、END語句塊

操作:一個或多個命令、函數、表達式,換行符或分號隔開,位於大括號內

變量或數組賦值
輸出命令
內置函數
控制流語句

awk腳本基本結構

awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file

 BEGIN語句塊、能夠使用模式匹配的通用語句塊、END語句塊
 三個部分是可選的,腳本通常是被單引號或雙引號中

awk的工作原理

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

 第一步:執行BEGIN{ commands }語句塊中的語句;
 第二步:從文件或標準輸入(stdin)讀取一行,然後執行pattern{ commands }語句塊,它逐行掃描文件,從第一行到最後一行重複這個過程,直到文件全部被讀取完畢。
 第三步:當讀至輸入流末尾時,執行END{ commands }語句塊。


 BEGIN語句塊在awk開始從輸入流中讀取行之前被執行,這是一個可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中。

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

 pattern語句塊中的通用命令是最重要的部分。如果沒有提供pattern語句塊,則默認執行{ print },即打印每一個讀取到的行,awk讀取的每一行都會執行該語句塊。

awk
awk

awk內置變量(預定義變量)

awk
awk

awk運算與判斷

awk

所有用作算術運算符進行操作,操作數自動轉爲數值,所有非數值都變爲0
> < 可以作爲字符串比較,也可以用作數值比較,關鍵看操作數如果是字符串就會轉換爲字符串比較。兩個都爲數字才轉爲數值比較

awk

awk高級輸入輸出

讀取下一條記錄

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

    cat 2.sh
    a
    b
    c
    d
    e

    awk 'NR%2==1{next}{print NR,$0;}' 2.sh
    2 b
    4 d

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

分析發現需要將包含有“web”行進行跳過,然後需要將內容與下面行合併爲一行

    cat 3.sh
    web01[192.168.2.100]
    httpd             
    tomcat            
    sendmail            
    web02[192.168.2.101]
    httpd             
    postfix           
    web03[192.168.2.102]
    mysqld            
    httpd             

    awk '/^web/{T=$0;next;}{print T":t"$0;}' 3.sh
    web01[192.168.2.100]:   httpd             
    web01[192.168.2.100]:   tomcat          
    web01[192.168.2.100]:   sendmail       
    web02[192.168.2.101]:   httpd             
    web02[192.168.2.101]:   postfix          
    web03[192.168.2.102]:   mysqld          
    web03[192.168.2.102]:   httpd             

簡單地讀取一條記錄

  awk getline用法:輸出重定向需用到getline函數。getline從標準輸入、管道或者當前正在處理的文件之外的其他輸入文件獲得輸入。它負責從輸入獲得下一行的內容,並給NF,NR和FNR等內建變量賦值。如果得到一條記錄,getline函數返回1,如果到達文件的末尾就返回0,如果出現錯誤,例如打開文件失敗,就返回-1。

  getline語法:getline var,變量var包含了特定行的內容。

當其左右無重定向符|或<時:getline作用於當前文件,讀入當前文件的第一行給其後跟的變量var或$0(無變量),應該注意到,由於awk在處理getline之前已經讀入了一行,所以getline得到的返回結果是隔行的。

當其左右有重定向符|或<時:getline則作用於定向輸入文件,由於該文件是剛打開,並沒有被awk讀入一行,只是getline讀入,那麼getline返回的是該文件的第一行,而不是隔行。

執行linux的date命令,並通過管道輸出給getline,
然後再把輸出賦值給自定義變量out,並打印它:
awk 'BEGIN{ "date" | getline out; print out }' test

執行shell的date命令,並通過管道輸出給getline,然後getline從管道中讀取並將輸入賦值給out,
split函數把變量out轉化成數組mon,然後打印數組mon的第二個元素:
awk 'BEGIN{ "date" | getline out; split(out,mon); print mon[2] }' test

命令ls的輸出傳遞給geline作爲輸入,循環使getline從ls的輸出中讀取一行,並把它打印到屏幕。
這裏沒有輸入文件,因爲BEGIN塊在打開輸入文件前執行,所以可以忽略輸入文件。
awk 'BEGIN{ while( "ls" | getline) print }'

關閉文件

awk中允許在程序中關閉一個輸入或輸出文件,方法是使用awk的close語句。

    close("filename")

filename可以是getline打開的文件,也可以是stdin,包含文件名的變量或者getline使用的確切命令。或一個輸出文件,可以是stdout,包含文件名的變量或使用管道的確切命令。

輸出到一個文件

awk中允許用如下方式將結果輸出到一個文件:

    echo | awk '{printf("hello word!n") > "datafile"}'
    或
    echo | awk '{printf("hello word!n") >> "datafile"}'

設置字段定界符

默認的字段定界符是空格,可以使用-F "定界符" 明確指定一個定界符:

    awk -F: '{ print $NF }' /etc/passwd
    或
    awk 'BEGIN{ FS=":" } { print $NF }' /etc/passwd

在BEGIN語句塊中則可以用OFS=“定界符”設置輸出字段的定界符。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章