jasmine214--love

          只有當你的內心總是充滿快樂、美好的愿望和寧靜時,你才能擁有強壯的體魄和明朗、快樂或者寧靜的面容。
          posts - 731, comments - 60, trackbacks - 0, articles - 0

          Shell 學習—AWK---kiki整理

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

          Shell 學習—AWK

          = = = 安裝awk

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

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

          = = =.awk語言具有某些特點,

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

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

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

           此外, awk內建有pipe功能, 可將處理中的數據傳送給外部的 Shell命令加以處理, 再將Shell命令處理后的數據傳回awk程序, 這個特點也使得awk程序很容易使用系統資源.

          = = =  awk程序的主要結構:

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

          Pattern1 { Actions1 }

          = = =  Actions 是什么?

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

          例如 :

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

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

          = = =  例子

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

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

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

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

          UNIX命令行上, 執行awk的語法為:

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

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

           

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

          "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的工作流程 :

          執行awk, 它會反復進行下列四步驟.

          自動從指定的數據文件中讀取一個數據行.

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

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

          當執行完程序中所有 Pattern { Actions } , 若數據文件中還有未讀取的數據, 則反復執行步驟1到步驟4.

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

          = = =  linux 文本以空格分隔的行就可以默認操作

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

          dengfang,0Rgbo2Kyn0hms

          huyibao,0R1d4zCYO3qxk

          dengfeng,0RUsQ9pz6kBPs

          gongfangping,0Ru/KhW.8Ove6

          liucaigeng,0Rekdi5B0sWfU

           

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

           

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

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

          所有員工最后之薪資率若仍低于100, 則以100.

          編寫awk程序打印新的員工薪資率報表.

           

          原文件:

          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

           

          例二,統計各科修課人數,并印出結果

           

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

          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] )}

          執行下列命令 :

          $awk -f course.awk reg.dat

          執行結果如下 :

            Graphics 2

                O.S. 2

            Discrete 3

                A.I. 1

                D.S. 1

               Arch. 2

           Algorithm 2

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

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

          平常讀入數據行時, END并不成立, 故其后的Actions 并不被執行;

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

          BEGIN END 有點類似, awk中另一個保留的Pattern.

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

           

          = = = awk中數組的特性

          使用字符串當數組的下標(index).

          使用數組前不須宣告數組名及其大小.

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

          這情況,有二項信息必須儲存:

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

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

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

          使用一個數組 Number[ ] :

          以課程名稱當 Number[ ] 的下標.

          Number[ ] 中不同下標所對映的元素代表修課人數.

          例如:

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

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

           

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

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

          BEGIN {

          while ( "who" | getline ) n++

          print n

          }

          并執行下列命令 :

          awk -f count.awk

          執行結果將會印出目前在線人數

          getline var

          pipe 變量

          變量 var(var省略時,表示置于$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 中如何利用系統資源

          : awk input 指令只有 getline 一個.

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

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

          上列awk程序中, "print$1, $2" 可能反復執行很多次, 其輸出的結果將先暫存于 pipe ,等到該程序結束時, 才會一并進行 "sort -k 1".

          須注意二點 : 不論 print $1, $2 被執行幾次, "sort -k 1" 的執行時間是 "awk程序結束時",

          [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

           

          = = = = 執行 awk 程序的幾種方式= = = =

          若欲執行該awk程序, 來印出文件 today_rpt1 today_rpt2 的內容時,

          必須于 UNIX 的命令行上執行下列命令 :

          方式一 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  #(未接任何數據文件文件名)

          將會發現: 此后鍵入的任何數據將逐行復印一份于屏幕上. 這情況不是機器當機 ! 是因為awk程序正處于執行中. 它正按程序指示, 將讀取數據并重新dump一次; 只因執行時未指定數據文件文件名, awk 便以stdin(鍵盤上的輸入)為數據來源. 讀者可利用這個特點, 設計可與awk即時聊天的程序.

           

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

          kiki

          kiki

           

           

          kiki

          kiki

           

           

          mina

          mina

           

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

           

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

           

          主站蜘蛛池模板: 章丘市| 武隆县| 徐水县| 永仁县| 铁岭县| 兴海县| 临颍县| 库车县| 彭泽县| 凤山县| 于田县| 东辽县| 磐安县| 三台县| 泸州市| 中江县| 乐业县| 礼泉县| 黄梅县| 得荣县| 光山县| 安图县| 临夏市| 团风县| 伊春市| 南投县| 新蔡县| 安泽县| 龙里县| 章丘市| 寻甸| 资兴市| 泗洪县| 永善县| 缙云县| 江永县| 巴青县| 行唐县| 鄂伦春自治旗| 闽清县| 萨嘎县|