文本處理工具三劍客之awk

文本處理工具:grep,sed,awk

awk:報告生成器,格式化文本輸出

AWK: Aho ,Weinberger,Kernighan

gawk:GNU awk

gawk – pattren  scanning  and  processing  language

基本語法:gawk  [options ] ‘program’ FILE….

    program:PATTERN{ACTION STATEMENTS}

        語句之間用分號分隔

選項:

    -F:指明輸入時用到的字段分隔符

    -v:var=value:自定義變量

        blob.png

  1. print

print item1,item2,…..

要點:

    1.以逗號作為分隔符

    2.輸出的各item可以是字符串,也可以是數字。也可以是當前記錄的字段,變量或者awk的表達式

    3.如果省略item,相當于print $0

實例:

 注意print里面的字符要用引號 引起來  

        blob.png

如果是變量就不要用引號了

        blob.png

省略item相當于print $0,而print “”相當于空,而print “ ”表現是空格

        blob.png

2.變量

    a,內建變量(分隔符)

        FS:inuput field seperator,默認為空白字符  

          OFS: output field seperator,默認為空白字符

          RS:inuput record seperator,輸入的換行符

          ORS:output record seperator,輸出的換行符

        blob.png

            blob.png

因為此處只定義了輸入時換行符為“”,并沒有定義輸出換行符,所有默認,在輸出的時候空格時要換行

,原默認要換行的時候也會換行

           blob.png

        

        NF:number of field,字段數量

               {print  NF} 顯示字段數 {print 1}

               ,{print  $NF}顯示最后一個字段,類似于{print $1}

          blob.png

          NR: number of field,行數 (如果兩個文件一起顯示,會直接連在一起,不會分開計數)

                {print  NR} 顯示行數

          blob.png 

          FNR:file number of field, 各文件分開計數行數

           blob.png   

          FILENAME:當前文件名

          blob.png

          ARGC:命令行參數的個數

          ARGV:數組,保存的是命令行所給定的各參數

          blob.png

    b.自定義變量

        1.-v var=value

            變量名區分大小寫

        blob.png

        2.在program中直接定義

        blob.png

3.printf命令

    格式化輸出:printf FORMAT ,item1,item2,….

        1.FORMAT是必須要給出的

        2.不會自動換行,需要顯示給出換行控制符,\n

        3.FORMAT需要分別為后面的每個item指定一個格式化符號

    格式符:

        %c:顯示字符的ASCII碼

        %d,%i:顯示十進制整數

        %e,%E:科學計數法數值顯示

        %f:顯示為浮點數

        %g,%G:以科學計數法或浮點形式顯示數值

        %s:顯示字符串

        %u:無符號整數

        %%:顯示%自身

  換行符記得加上,不然看起來就很蠢了!!

         blob.png  

每個item都要有一個FORMAT,否則item就不成立了,不顯示了

        blob.png    

    

    修飾符:

        #[.#]格式符:

            例如%3.1f==>第一個數字控制顯示寬度,第二個數字表示小數點后的精度

        -:表示左對齊,默認為右對齊

        +:表示數值的符號 

        表示左對齊           

        blob.png        

        默認為右對齊

        blob.png

4.操作符

    算術運算操作符

        +,-,*,/,^,% 依次為加減乘除 次方取模

        -x:負值

        +x:轉換為數值

    字符串操作符:沒有符號的操作符,字符串連接

    賦值操作符

        =,+=,-=,*=,/=,^=,%=

    比較操作符:

        >,>=,<,<=,!=,==

 blob.png

模式匹配:

    ~:是否匹配

    !~:是否不匹配

邏輯操作符:

    &&: 與

    ||:或

     ?。悍?/p>

顯示/etc/passwd文件中uid=0或者大于1000的行顯示第1,3列,分隔符為”:“

blob.png

顯示/etc/passwd文件中uid大于等于0小于等于1000的行顯示第1,3列,分隔符為”:“

blob.png

顯示/etc/passwd文件中uid不等于0的行顯示第1,3列,分隔符為”:“

blob.png

函數調用:

     function_name(argu1,argu2,…..)  

條件表達式:

      selector ? if-true-expression:if-false-expression

      如果為真執行true,否則執行false

實例:

如果uid大于1000,則usertype為common,否則為system,,輸出每行第一列及變量usertype

awk -F: '{$3>=1000?usertype="common":usertype="system";printf "%15s:%-s\n",$1,usertype}' /etc/passwd

blob.png

5.PATTERN

    1.empty:空模式,匹配每一行;

    2./regular expression/:僅處理被此處的模式匹配的行

     !/regular expression/:僅處理被此模式匹配的行之外的行

    例:顯示以UUID開頭的行,顯示第一列,可個為分隔符

       顯示不以UUID開頭的行,顯示第一列,可個為分隔符

    blob.png

    3.relational expression:關系表達式,結果有”真“有”假“,結果為”真“才會被處理

        真:結果為非0值,非空字符串

        假:結果為空字符串或0值

    示例:

    blob.png

    blob.png

    blob.png

    4.line ranges:行范圍

        startline,endline: /pat1/,/pat2/不支持直接給出數字格式

    顯示從以root開頭的行開始,到以nobody開頭的行結束,顯示第一列,以”:“為分隔符

    blob.png

    顯示行號小于10或者大于40的行,取出第一列,分隔符為”:“

    blob.png

    5.NEGIN/END模式

        BEGIN{}:僅在開始處理文件中的文本之前執行一次

        END{}:僅在文本處理完成之后執行一次 

    示例:

    blob.png

    blob.png     

  blob.png

     結果為真處理,為假不處理

    blob.png

    顯示偶數行和奇數行

    blob.png

    此例來解釋為何上面是奇數和偶數

    說明:i初始值為0,第一行i=!i,則i=1,結果為真,處理,所以上面第一行顯示

    第二行時,i初始值為1,i=!i,則i=0,結果為假,不處理,所有上面第二行沒顯示,

    下面就是循環賦值了,每到技奇數行i=1,偶數行i=0,所以才有上面的效果

    (注意1為真,0為假,非1的結果就是假了,而非0的結果就是真了)

   blob.png

    如果我們使得i的初始值為真,那么結果就和上面的相反了,顯示的是偶數行

   blob.png

    6.常用的action

          1.表達式Expressions

          2.控制語句Control statements  :if  while等

          3.組合語句Compound statements :組合語句

          4.輸入語句input  statements

          5.輸出語句outut  statements :print等

    7.控制語句

        if (condition) { statements } 

          if (condition) { statements }  else  { statements }

          while (condition) { statements }

          do  { statements } while (condition)

          for (expr1;expr2;expr3) { statements }

          break

          continue

          delete  array[index]

          delete array

          exit

          { statements  }

awk控制語句if-else

    語法:if(condition)  statements   [ else  statements]

        if(condition1) {statement1}else if(condition2) {statement2} esle{statement3}

    使用場景:對awk取得的整行或某個字段做條件判斷

    示例:

    如果uid大于1000就顯示此行中的第1,3列,分隔符為”:“

    blob.png

    如果uid大于1000則顯示為conmmon user,否則顯示system user,并顯示第1,3列,分隔符為”:“

    blob.png

    說明 90分以下為very good 60-90為good,60分以下為不及格  blob.png

    以/dev開頭的行,分隔符為%,取第一列,然后顯示的行中默認可個為分隔符,最后一行如果大于20,則顯示第1行和最后一行

    blob.png

awk控制語句=====while循環

語法:while(condition){statement}

條件為”真“,進入循環;條件為”假“,退出循環

使用場景:

    對一行內的多個字段注意類似處理時使用

    對數組中那個的各元素逐一處理時使用

示例:

    說明:文件為/etc/grub.cfg,匹配以任意數量的空格開頭后面跟Linux16的行,做while循環,初始值i=1,判斷題條件為i<NF(每行字段數),

      i++自增,打印內容為每行的每個字段,以及此字符個數。默認分隔符為" "

blob.png

    說明:在上面的基礎上加了一個判斷條件,字段中字符分個數大于等于10,打印內容為每行的每個字段,以及此字符個數。默認分隔符為" "

blob.png

awk控制語句=====do-while循環

語法:do {statement;…}while(condition)

意義:無論真假,至少執行一次循環

示例:

    blob.png

    說明不同:

    后面的i沒有爭議,那么i++和++i的卻別就在于,先后順序,

    第一個是先顯示i,然后才自增賦值的,所以值為

    第二個是先自增賦值,然后才顯示i的,所以值為1

    blob.png

awk控制語句===for循環

語法:for(expr1;expr2;expr3){statement;…}

常見用法:

    for(variable assignment;condition;iteration process){for-body}

特殊用法:能夠遍歷數組中的元素;

    語法: :for(var in array) {for-body}

示例:

awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg

blob.png

性能比較:

time (awk 'BEGIN{total=0;for(i=0;i<=10000;i++){total+=i;};print total;}')
time(total=0;for i in {1..1000000};do total=$(($total+i));done;echo $total)
time(for ((i=0;i<=1000000;i++));do let total+=i;done;echo $total)

結果很顯然是awk運算最快,想想也知道了,這章博客主要內容就是awk,做這個比較肯定想體現akw是有多牛逼咯

blob.png

awk控制語句====>switch語句

語法:swicth(expression){case VALUE1 or /REGEXP/:statement;case VALUE2 or /REGEXP2/:statement;…;default:statement}

break和continue

示例:

break表示當i=66的時候中斷此循環,所以結果是1加到65

continue表示當i為偶數的時候終止了本輪循環,所以結果為奇數相加

blob.png

break[n]

continue[n]

next:

提前結束對本行處理而直接進入下一輪處理(awk自身循環)

說明:當uid為奇數時,提前結束本行,跳過本行要處理的,

blob.png

awk數值:array[index-expression]

index-expression:

    1.可使用任意字符串;字符串要使用雙引號括起來

    2.如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其值初始化為“空串”

若要判斷數組中是否存在某元素,要使用“index in array”格式進行遍歷

示例:

blob.png

 awk ‘!a[$0]++’ dupfile

若要遍歷數組中的每個元素,要使用for循環

for(var in array) {for-body}

注意:var會遍歷array的每個索引

示例:

blob.png

說明:統計tcp開頭的單詞中最后一字段出現次數

blob.png

說明:統計第一段ip出現的次數

blob.png

awk函數:

    rand():返回0和1之一個隨機數

[root@localhost ~]# awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'

blob.png

字符串處理:

length([s]):返回指定字符串的長度

sub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并將第一個匹配的內容替換成s

    echo "2008:08:08 08:08:08" | awk 'sub(/:/,“-",$1)'

gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并全部替換為s所表示的內容

    echo "2008:08:08 08:08:08" | awk ‘gsub(/:/,"",$1)'

blob.png

split(s,array ,[r]):以r為分隔符,切割字符s,并將切割后的結果保存至array所表示的數組中,第一個索引值為1

第二個索引值為2…

blob.png

自定義函數

格式

    function name (parameter,parameter,….){

            statements

            return exprossion

    }

示例:

#!/bin/bash
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN{a=3;b=2;print max(a,b)}

blob.png

  1 #!/bin/bash
  2 function max(v1,v2) {
  3 v1>v2?var=v1:var=v2
  4 return var
  5 }
  6 BEGIN{print max(a,b)}

blob.png

awk中調用shell命令

system命令

空格是awk中的字符串連接符,如果system中需要使用awk中的變量可以使用空格分隔,或者說除了awk

的變量外其他的一律用“”引用起來

blob.png

awk腳本

將awk程序寫成腳本,直接調用或執行

示例:

blob.png

blob.png

向awk腳本傳遞參數

格式:

    awkfile var=value var2=value2… Inputfile

[root@localhost bin]# cat test.awk 
#!/bin/awk -f
{if($3<=min||$3>=max)print $1,$3}
[root@localhost bin]# test.awk -F: min=10 max=1000 /etc/passwd

blob.png

練習

1 、 統計/etc/fstab文件中每個文件系統類型出現 的次數

awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab

blob.png

2、 、 統計/etc/fstab 文件中每個單詞出現的次數

[root@localhost bin]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab
man 1
and/or 1
/mnt 1
maintained 1
xfs 4
14:09:19 1
UUID=b39702a5-31f8-4fca-96cc-3389a0a58059 1
Accessible 1
# 7
are 1
defaults 5
blkid(8) 1
/ 1
0 13
See 1
3 1
Mon 1
Created 1
on 1
usrquota,grpquota 1
mount(8) 1
ext4 2
acl 1
anaconda 1
fstab(5), 1
/boot 1
/testdir 1
/usr 1
UUID=bd915a87-493a-415b-8d2f-8cedaab84792 1
findfs(8), 1
2016 1
/home 1
'/dev/disk' 1
UUID=5bc0405e-cf7a-4d60-8c0c-a6daa1dd71d2 1
by 2
/etc/fstab 1
UUID=12294f2d-4b7d-4f64-a8b7-1522fe51d0b2 1
pages 1
UUID=d8150c22-3804-4d3e-bd18-8f44e93bb978 1
more 1
25 1
info 1
UUID=8d687919-88d4-4c2a-9e0b-473cd13bb785 1
swap 2
Jul 1
UUID=14efdeb1-9880-49dc-aaa0-321c4eb4816a 1
filesystems, 1
reference, 1
for 1
under 1

原創文章,作者:qiuwei,如若轉載,請注明出處:http://www.www58058.com/47950

(0)
qiuweiqiuwei
上一篇 2016-09-22
下一篇 2016-09-22

相關推薦

  • Linux基礎小模塊

    1.基礎知識小塊:shell 由shell程序的自帶命令:即為內置命令(builtin) 獨立的可執行程序文件、文件名 :即為外部命令  [root@localhost~]#ls      ~用戶當前所在目錄  #:命令提示符(管理員帳號root)  $:普通用戶   &nbsp…

    Linux干貨 2016-08-05
  • 文件系統上的權限管理

                        文件系統上的權限管理: 一 、三種權限       &nbs…

    Linux干貨 2017-04-03
  • Linux 基礎(三)——用戶管理&正則表達式

    1、  列出當前系統上所有已經登錄的用戶的用戶名,注意:同一個用戶登錄多次,則只顯示一次即可。 who | cut -d " " -f1 | uniq 2、  取出最后登錄到當前系統的用戶的相關信息。 last -1 | cut -d " " -f1 | head -1 | id 3、  …

    Linux干貨 2016-11-08
  • nfs實驗

    實驗要求: (1) 創建一個共享mydata,路徑為/mysql/data,客戶端1掛載至/mydata;而后客戶端1主機安裝mysql或mariadb,將數據目錄設定為/mydata,要確保mysql服務能正常 運行,但數據目錄位于nfs server上; (2) 客戶端2主機使用類似客戶端1主機的方式掛載mydata共享至本地的/mydata目錄,而后,…

    Linux干貨 2016-10-24
  • 初識Linux

                              初認識Linux 1.1 Linux的登錄界面 在虛擬機安裝CentOS 7中有提到,我在安裝Linux操作系統的時候,采用的是命令行界面的登錄方式,當然也有像Windows那樣…

    Linux干貨 2016-10-27
  • 誤刪除libc.so.6時,該怎么恢復

           一周一周光陰似流水,轉瞬即逝,又到了該說點什么的時候了。這周老師給我們出了一道實驗題,內容是當你不小心誤刪除了libc.so.6這個庫文件時,怎么恢復。意不意外?驚不驚喜?那下面就來簡單說說(呃……為什么不是詳細說說呢,因為這個這個水平有限,也只能是理解多少,給…

    2017-08-11
欧美性久久久久