jasmine214--love

          只有當(dāng)你的內(nèi)心總是充滿快樂、美好的愿望和寧靜時(shí),你才能擁有強(qiáng)壯的體魄和明朗、快樂或者寧靜的面容。
          posts - 731, comments - 60, trackbacks - 0, articles - 0

          Shell 學(xué)習(xí)—AWK---kiki整理

          Posted on 2011-01-27 16:21 幻海藍(lán)夢 閱讀(454) 評論(0)  編輯  收藏 所屬分類: Linux 、Shell

          Shell 學(xué)習(xí)—AWK

          = = = 安裝awk

          root@kiki-desktop:~/shell# apt-get install gawk gawk-doc

          = = = awk 是一種程序語言. 它具有一般程序語言常見的功能.

          = = =.awk語言具有某些特點(diǎn),

          : 使用直譯器(Interpreter)不需先行編譯;

           變量無類型之分(Typeless), 可使用文字當(dāng)數(shù)組的下標(biāo)(Associative Array)...等特色. 因此, 使用awk撰寫程序比起使用其它語言更簡潔便利且節(jié)省時(shí)間.

           awk還具有一些內(nèi)建功能, 使得awk擅于處理具數(shù)據(jù)行(Record), 字段(Field)型態(tài)的資料;

           此外, awk內(nèi)建有pipe功能, 可將處理中的數(shù)據(jù)傳送給外部的 Shell命令加以處理, 再將Shell命令處理后的數(shù)據(jù)傳回awk程序, 這個特點(diǎn)也使得awk程序很容易使用系統(tǒng)資源.

          = = =  awk程序的主要結(jié)構(gòu):

          awk程序中主要語法是 Pattern { Actions}, 故常見之awk 程序其型態(tài)如下 :

          Pattern1 { Actions1 }

          = = =  Actions 是什么?

          Actions 是由許多awk指令構(gòu)成. awk的指令與 C 語言中的指令十分類似.

          例如 :

          awk I/O指令 : print, printf( ), getline...

          awk 流程控制指令 : if(...){..} else{..}, while(...){...}...

          = = =  例子

          有時(shí)語法 Pattern { Actions }, Pattern 部分被省略,只剩 {Actions}.這種情形表示 "無條件執(zhí)行這個 Actions".

          50 > 23 {print "Hello! The word!!" }

          "banana" ~ /123/ { print "Good morning !" }

          # awk '{print $2,$3*$4}' emp

          UNIX命令行上, 執(zhí)行awk的語法為:

          $awk 'awk程序' 欲處理的資料文件文件名

          # cat file1 | awk -F , {'print $1,$2'}

           

          = = =  例如 : awk 從資料文件 emp.dat 中讀入第一筆數(shù)據(jù)行

          "A125 Jenny 100 210" 之后, 程序中:

          $0 之值將是 "A125 Jenny 100 210"

          $1 之值為 "A125"

          $2 之值為 "Jenny"

          $3 之值為 100

          $4 之值為 210

          $NF 之值為 4

          $NR 之值為 1

          $FILENAME 之值為 "emp.dat"

          = = =  awk的工作流程 :

          執(zhí)行awk時(shí), 它會反復(fù)進(jìn)行下列四步驟.

          自動從指定的數(shù)據(jù)文件中讀取一個數(shù)據(jù)行.

          自動更新(Update)相關(guān)的內(nèi)建變量之值. : NF, NR, $0...

          依次執(zhí)行程序中 所有 Pattern { Actions } 指令.

          當(dāng)執(zhí)行完程序中所有 Pattern { Actions } 時(shí), 若數(shù)據(jù)文件中還有未讀取的數(shù)據(jù), 則反復(fù)執(zhí)行步驟1到步驟4.

          awk會自動重復(fù)進(jìn)行上述4個步驟, 使用者不須于程序中編寫這個循環(huán) (Loop).

          = = =  linux 文本以空格分隔的行就可以默認(rèn)操作

                                      以其他分隔如, ;等等,就可以用awk –f 操作

          dengfang,0Rgbo2Kyn0hms

          huyibao,0R1d4zCYO3qxk

          dengfeng,0RUsQ9pz6kBPs

          gongfangping,0Ru/KhW.8Ove6

          liucaigeng,0Rekdi5B0sWfU

           

          = = =  print 的參數(shù)間彼此以 "," (逗號) 隔開, 印出數(shù)據(jù)時(shí)彼此間會以空白隔開.

           

          例一,選擇符合指定條件的記錄

          組裝部門員工調(diào)薪5%,(組裝部門員工之ID"A"開頭)

          所有員工最后之薪資率若仍低于100, 則以100計(jì).

          編寫awk程序打印新的員工薪資率報(bào)表.

           

          原文件:

          A125 Jenny 100 210

          A341 Dan 110 215

          P158 Max 130 209

          P148 John 125 220

          A123 Linda 95 210

           

          [root@kiki-desktop:~/shell# cat adjust1.awk

          $1 ~ /^A.*/ {$3*=1.05} $3<100 {$3=100}

          {printf("%s %8s %d\n",$1,$2,$3)}

           

          root@kiki-desktop:~/shell# cat emp

          A125 Jenny 100 210

           

          A341 Dan 110 215

           

          P158 Max 130 209

           

          P148 John 125 220

           

          A123 Linda 95 210

           

          root@kiki-desktop:~/shell# awk -f  adjust1.awk  emp

          A125    Jenny 105

                    100

          A341      Dan 115

                    100

          P158      Max 130

                    100

          P148     John 125

                    100

          A123    Linda 100

           

          例二,統(tǒng)計(jì)各科修課人數(shù),并印出結(jié)果

           

          此為一學(xué)生注冊的資料文件; 第一欄為學(xué)生姓名, 其后為該生所修課程.

          Mary O.S. Arch. Discrete

          Steve D.S. Algorithm Arch.

          Wang Discrete Graphics O.S.

          Lisa Graphics A.I.

          Lily Discrete Algorithm

          .

          建立如下程序,并取名為 course.awk:

          { for( i=2; i <= NF; i++) Number[$i]++ }

          END{for(course in Number) printf("%10s %d\n", course, Number[course] )}

          執(zhí)行下列命令 :

          $awk -f course.awk reg.dat

          執(zhí)行結(jié)果如下 :

            Graphics 2

                O.S. 2

            Discrete 3

                A.I. 1

                D.S. 1

               Arch. 2

           Algorithm 2

          解說:指令中END awk之保留字, Pattern 的一種.

          END 成立(其值為true)的條件是: "awk處理完所有數(shù)據(jù), 即將離開程序時(shí). "

          平常讀入數(shù)據(jù)行時(shí), END并不成立, 故其后的Actions 并不被執(zhí)行;

          唯有當(dāng)awk讀完所有數(shù)據(jù)時(shí), Actions才會被執(zhí)行 ( 注意, 不管數(shù)據(jù)行有多少筆, END僅在最后才成立, 故該Actions僅被執(zhí)行一次.)

          BEGIN END 有點(diǎn)類似, awk中另一個保留的Pattern.

          唯一不同的是: " BEGIN Pattern Actions 于程序一開始執(zhí)行時(shí), 被執(zhí)行一次."

           

          = = = awk中數(shù)組的特性

          使用字符串當(dāng)數(shù)組的下標(biāo)(index).

          使用數(shù)組前不須宣告數(shù)組名及其大小.

          例如: 希望用數(shù)組來記錄 reg.dat 中各門課程的修課人數(shù).

          這情況,有二項(xiàng)信息必須儲存:

          (a) 課程名稱, : "O.S.","Arch.".. ,共有哪些課程事先并不明確.

          (b)各課程的修課人數(shù). : 有幾個人修"O.S."

          awk中只要用一個數(shù)組就可同時(shí)記錄上列信息. 其方法如下:

          使用一個數(shù)組 Number[ ] :

          以課程名稱當(dāng) Number[ ] 的下標(biāo).

          Number[ ] 中不同下標(biāo)所對映的元素代表修課人數(shù).

          例如:

          2個學(xué)生修 "O.S.", 則以 Number["O.S."] = 2 表之.

          若修"O.S."的人數(shù)增加一人, Number["O.S."] = Number["O.S."] + 1 Number["O.S."]++ .

           

          例三,寫一個awk程序來打印出線上人數(shù).

          將下列程序建文件, 命名為 count.awk

          BEGIN {

          while ( "who" | getline ) n++

          print n

          }

          并執(zhí)行下列命令 :

          awk -f count.awk

          執(zhí)行結(jié)果將會印出目前在線人數(shù)

          getline var

          pipe 變量

          變量 var(var省略時(shí),表示置于$0)

           

          例四,重定向輸出到文件

           

          root@kiki-desktop:~/shell# cat arr.dat

          1034 7:26

           

          1025 7:27

           

          1101 7:32

           

          1006 7:45

           

          1012 7:46

           

          1028 7:49

           

          1051 7:51

           

          1029 7:57

           

          1042 7:59

           

          1008 8:01

           

          1052 8:05

           

          1005 8:12

          root@kiki-desktop:~/shell# cat reformat1.awk

          BEGIN { print " ID Number Arrival Time" > "today_rpt1"

           

          print "===========================" > "today_rpt1"

           

          }

           

          { printf(" %s %s\n", $1,$2 ) > "today_rpt1" }

          root@kiki-desktop:~/shell#

          root@kiki-desktop:~/shell#

          root@kiki-desktop:~/shell# awk -f reformat1.awk arr.dat

          root@kiki-desktop:~/shell#

           

          = = = awk 中如何利用系統(tǒng)資源

          : awk input 指令只有 getline 一個.

          awk output 指令有 print, printf() 二個.

          a 語法中, awk所輸出的數(shù)據(jù)將轉(zhuǎn)送往 Shell , Shell 的命令進(jìn)行處理.以上例而言, print 所輸出的數(shù)據(jù)將經(jīng)由 Shell 命令 "sort -k 1" 排序后再送往屏幕(stdout).

          上列awk程序中, "print$1, $2" 可能反復(fù)執(zhí)行很多次, 其輸出的結(jié)果將先暫存于 pipe ,等到該程序結(jié)束時(shí), 才會一并進(jìn)行 "sort -k 1".

          須注意二點(diǎn) : 不論 print $1, $2 被執(zhí)行幾次, "sort -k 1" 的執(zhí)行時(shí)間是 "awk程序結(jié)束時(shí)",

          [a. 語法] awk output 指令 | "Shell 接受的命令"

          ( : print $1,$2 | "sort -k 1" )

           

          5,

          root@kiki-desktop:~/shell# awk '

          > BEGIN{

          > system("date > date.dat")

          > getline < "date.dat"

          > print "Today is ", $2, $3

          > }

          > '

          Today is  Jan 26

           

          = = = = 執(zhí)行 awk 程序的幾種方式= = = =

          若欲執(zhí)行該awk程序, 來印出文件 today_rpt1 today_rpt2 的內(nèi)容時(shí),

          必須于 UNIX 的命令行上執(zhí)行下列命令 :

          方式一 awk -f mydump.awk today_rpt1 today_rpt2

          方式二 awk '{print}' today_rpt1 today_rpt2第二種方式系將awk 程序直接寫在 Shell 的命令行上, 這種方式僅適合較短的awk程序.

          方式三 建立如下之 shell script, 并取名為 mydisplay, $ ./mydisplay today_rpt1 today_rpt2

           

          #!/bin/sh

          # 注意以下的 awk ' 之間須有空白隔開

          awk '

          {print}

          ' $*

          # 注意以上的 ' $* 之間須有空白隔開

           

          5,$ ./mydisplay  #(未接任何數(shù)據(jù)文件文件名)

          將會發(fā)現(xiàn): 此后鍵入的任何數(shù)據(jù)將逐行復(fù)印一份于屏幕上. 這情況不是機(jī)器當(dāng)機(jī) ! 是因?yàn)?/span>awk程序正處于執(zhí)行中. 它正按程序指示, 將讀取數(shù)據(jù)并重新dump一次; 只因執(zhí)行時(shí)未指定數(shù)據(jù)文件文件名, awk 便以stdin(鍵盤上的輸入)為數(shù)據(jù)來源. 讀者可利用這個特點(diǎn), 設(shè)計(jì)可與awk即時(shí)聊天的程序.

           

          root@kiki-desktop:~/shell# ./mydisplay

          kiki

          kiki

           

           

          kiki

          kiki

           

           

          mina

          mina

           

          6,改變 awk 切割字段的方式 & 自定義函數(shù)

           

          范例 : ] 承接 6.2 的例子, 若八點(diǎn)為上班時(shí)間, 請加注 "*"于遲到記錄之前, 并計(jì)算平均上班時(shí)間.

           

          主站蜘蛛池模板: 石屏县| 清镇市| 玛纳斯县| 随州市| 南陵县| 循化| 祁东县| 南召县| 云龙县| 香港| 永靖县| 抚宁县| 吉林市| 山东省| 贺州市| 宁乡县| 盐城市| 寿宁县| 多伦县| 宁强县| 南溪县| 宿松县| 和平区| 沐川县| 扶沟县| 云林县| 宁远县| 芮城县| 常德市| 姚安县| 正蓝旗| 德格县| 台北市| 莲花县| 曲靖市| 永胜县| 若羌县| 光泽县| 孟津县| 嘉祥县| 叙永县|