Linux文本處理之awk

GAWK:報告生成器太示,格式化文本輸出

    awk [options] ‘program’ var=value file…

    awk [options] -f programfile var=value file…

    awk [options] 'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file ...


  awk程序組成部分:


    BEGIN語句塊、能夠使用模式匹配的通用語句塊香浩、END語句塊


    選項:

      -F:指明輸入時用到的字段分割符类缤;

      -v var=value:自定義變量

      -f:指定awk腳本,從腳本中讀取program


    基本格式:


      awk [options] 'program' file...

      program:pattern{action statements;...}? 通常在單引號或雙引號中弃衍;

      pattern與action:

        pattern部分決定動作語句何時觸發(fā)及事件

          BEGIN:模式匹配之前要執(zhí)行的動作


          END:模式匹配結束之后要執(zhí)行的動作

        action statements對數據進行處理呀非,放在{}內指明;

          print? $0,$!.......$(NF-1)........$NF(最后一列)


    分隔符,域,記錄:


      awk執(zhí)行時镜盯,由分隔符分隔的字段(域)標記$1,$2...$n稱為域標識岸裙。$0為所有域。

      文件的每一行稱為記錄速缆;

      省略action降允,則默認執(zhí)行print $0的操作;




awk的工作原理:

  1)艺糜、執(zhí)行BEGIN{action;...}語句塊中的語句剧董;

  2)、從文件或標準輸入(stdin)讀取一行破停,然后執(zhí)行pattern{action;...}語句塊翅楼,它會逐行掃描文件,從第一行到最后一行重復這個過程真慢,知道文件被全部讀取完畢毅臊;

  3)、當讀至輸入流末尾時黑界,執(zhí)行END{action;...}語句塊


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


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

  pattern語句塊中的通用命令是最重要的部分烛占,也是可選的胎挎。如果 沒有提供pattern語句塊,則默認執(zhí)行{ print }忆家,即打印每一個讀取到的行犹菇,awk讀取的每一行都會執(zhí)行該語句塊? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

print格式:print item1,item2,...

      1)、逗號為分隔符弦赖;

      2)、輸出的個item可以是字符串浦辨,也可以是當前記錄的字段蹬竖、變量或awk的表達式沼沈;

      3)、如省略item币厕,相當于print $0列另;



     awk '{print "hello,awk"}'

     awk –F: '{print}' /etc/passwd         # -F指定分割符為? :冒號

     awk –F: '{print “wang”}' /etc/passwd


    awk –F: '{print $1}' /etc/passwd

    awk –F: '{print $0}' /etc/passwd

    awk –F: '{print $1”\t”$3}' /etc/passwd

    tail –3 /etc/fstab |awk '{print $2,$4}'


    變量:

      FS:輸入字段分隔符,默認為空白字符旦装;


1

awk -v FS=':' '{print $1,FS,$3}' file


      OFS:輸出字段分隔符页衙,默認為空白字符;指定輸出時的分隔符是什么阴绢,一般可以進行分隔符號替換店乐,類似下面的ORS的作用



      awk -v FS=':' -v OFS=':' '{print $1,$2,$3}' file

      [root@mysql-141 ~]# awk -v FS=':' -v OFS='#' '{print $1,$2,$3}' /etc/passwd

      root#x#0

      bin#x#1

      daemon#x#2

      adm#x#3




      RS:輸入記錄分隔符,指定輸入時的換行符呻袭,原換行符仍有效眨八;


      awk -v RS=' ' '{print}' file


      ORS:輸出記錄分隔符,輸出時用指定符號代替換行符左电;


      awk -v RS=' ' -v ORS='$$$' '{print}' file


      NF:字段數量



      awk -F: '{print NF}' file

      awk -F: '{print $(NF-1)}' file

      # 顯示文件的第一列廉侧,第三列,倒數第二列和最后一列

        [root@mysql-141 ~]# awk -F : '{print $1,$2,$(NF-1),$NF}' /etc/passwd

        root x /root /bin/bash

        bin x /bin /sbin/nologin

        daemon x /sbin /sbin/nologin

        adm x /var/adm /sbin/nologin




      NR:行號


      awk -F: '{print NR,$1}' file?? # 與FNR類似

      awk END'{print NR}' file

      [root@mysql-141 ~]# awk END'{print NR}' /etc/passwd  #將文件內容讀取完成之后篓足,統(tǒng)計行數

       26


      awk 'NR==2,NR==6{print NR,$0}}' file  #顯示文件2-6行




      FNR:各文件的行號分別計數段誊;



      awk -F: '{print FNR,$1}' file1 file2...

      [root@mysql-141 ~]# awk -F: '{print FNR,$1}' /etc/passwd

      1 root

      2 bin

      3 daemon

      4 adm

      5 lp

      6 sync

      7 shutdown

      8 halt




      FILENAME:當前文件名;文件內容有多少行栈拖,awk就會輸出多少行


     awk '{print FILENAME}' FILE1 FILE2...

      [root@mysql-141 ~]# awk '{print FILENAME}' /etc/passwd |wc -l

      26

      [root@mysql-141 ~]# wc -l /etc/passwd

      26 /etc/passwd



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


      awk 'BEGIN {print ARGV[0]}' /etc/fstab /etc/inittab

      awk 'BEGIN {print ARGV[1]}' /etc/fstab /etc/inittab

      [root@mysql-141 ~]# awk 'BEGIN {print ARGV[1]}' /etc/fstab /etc/inittab      # 相當于shell里面的$1 $2 $3 的概念

      /etc/fstab

      [root@mysql-141 ~]# awk 'BEGIN {print ARGV[2]}' /etc/fstab /etc/inittab

      /etc/inittab

      [root@mysql-141 ~]# awk 'BEGIN {print ARGV[0]}' /etc/fstab /etc/inittab

      awk

      [root@mysql-141 ~]# awk 'BEGIN {print ARGV[3]}' /etc/fstab /etc/inittab





    算術操作符:

      x+y x-y x*y x/y x^y x%y

      -x:轉換為負數辱魁;

      +x:轉換為數值烟瞧,變量通過+連接運算,自動強制將字符串轉為整形染簇,非數字變成0参滴,發(fā)現第一個非數字字符,后面的自動忽略锻弓;

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

    賦值操作符:


      =??? +=??? -=???? *=????? /=????? %=???? ^=????? ++????? --

    比較操作符:


      ==?? !=?? >??? >=??? <??? <=



    模式匹配符:

      ~:左邊的內容是否被右邊的模式包含匹配


      ?!~:是否不匹配;


1

[root@mysql-141 ~]# awk -F: '$0 ~ /root/{print $1}' /etc/passwd?   # 以:為分隔符青灼,匹配全部內容包含root的行暴心,打印第一列

       root

       operator


      [root@mysql-141 ~]# awk '$0 ~ "^root"' /etc/passwd       # 匹配所有內容,期初以root開頭的行

       root:x:0:0:root:/root:/bin/bash


      [root@mysql-141 ~]# awk -F: '$3==0' /etc/passwd        # 匹配以冒號為分隔符杂拨,第三列是0的行

      root:x:0:0:root:/root:/bin/bash




cat >>/tmp/reg.txt<<EOF

Zhang??? Dandan??????? 41117397??? :250:100:175

Zhang??? Xiaoyu??????? 390320151??? :155:90:201

Meng??? Feixue??????? 80042789??? :250:60:50

Wu??? Waiwai??????? 70271111??? :250:80:75

Liu??? Bingbing??? 41117483??? :250:100:175

Wang??? Xiaoai??????? 3515064655??? :50:95:135

Zi??? Gege??????? 1986787350??? :250:168:200

Li??? Youjiu??????? 918391635??? :175:75:300

Lao??? Nanhai??????? 918391635??? :250:100:175

EOF

操作符:


      與&&


      ?或||


      ?非专普!



示例:

[root@mysql-141 ~]# awk -F : '$3>=0 && $3<=1000 {print $1}' /etc/passwd

root

bin

daemon

adm

lp


[root@mysql-141 ~]# awk -F : '$3==0 || $3>=1000 {print $1}' /etc/passwd

root




[root@mysql-141 ~]# awk -F : '!($3==0) {print $1}' /etc/passwd

bin

daemon

adm

lp


[root@mysql-141 ~]# awk -F : '!($3>=500) {print $3}' /etc/passwd

0

1

2

3

4

5

6




    awk PATTERN:

      1)、如果未指定:空模式弹沽,匹配每一行檀夹;

      2)筋粗、/regular expression/:僅處理能夠被模式匹配到的行,需要用//括起來炸渡;


awk '/^UUID/{print $1}' /etc/passwd

awk '!/^UUID/{print $1}' /etc/passwd

      3)娜亿、relational expression:關系表達式,結果未"真"才會被處理蚌堵;

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

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


awk -F : 'i=1;j=1{print i,j}' /etc/passwd

awk '!0' /etc/passwd ; awk '!1' /etc/passwd

awk –F : '$3>=1000{print $1,$3}' /etc/passwd

awk -F : '$3<1000{print $1,$3}' /etc/passwd

[root@mysql-141 ~]# awk -F : '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd

root /bin/bash

lipeng /bin/bash


[root@mysql-141 ~]# awk -F : '$NF ~ /nologin$/{print $1,$NF}' /etc/passwd

bin /sbin/nologin

daemon /sbin/nologin

adm /sbin/nologin

lp /sbin/nologin

mail /sbin/nologin

uucp /sbin/nologin



      4)督赤、line ranges:行范圍:

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



[root@mysql-141 ~]# awk -F: '/^root\>/,/^nobody\>/{print $1}' /etc/passwd

root

bin

daemon

adm

lp

nobody

[root@mysql-141 ~]# awk -F: '(NR>=10&&NR<=20){print NR,$1}' /etc/passwd

10 uucp

11 operator

12 games

13 gopher

14 ftp


  awk數組概念:

預備知識: 了解兩種awk運算方法

    1) 累加運算 1+1+1

      i=i+1 i初始狀態(tài)為0

      i++

      eg: 統(tǒng)計/etc/services文件中空行數量

      第一個里程: 找出文件中空行信息

      awk '/^$/' /etc/services


      第二個里程: 統(tǒng)計空行數量

      awk '/^$/{i=i+1;print i}' /etc/services


PS: awk中所有字符串信息都會識別為變量名稱信息, 調取變量是不需要加上$符號

awk中想顯示指定字符串信息, 需要在字符串外面加上雙引號信息



[root@oldgirl ~]# awk '/^$/{i=i+1;print i}' /etc/services

1??????? #? i=i+1 i=0 i=0+1 --> i=1

2     #? i=i+1 i=1 i=1+1 --> i=2

3     #? i=2 i=2+1 --> i=3

4

5

6

7

8

9

10

11

12

13

14

15

16



[root@oldgirl ~]# awk '/^$/{i=i+1}END{print i}' /etc/services  # 將文件內容加載完之后,做出統(tǒng)計

16



    2) 求和運算 10+20+5

       i=i+$n i的初始狀態(tài)為0?? $n取第幾列數值信息



[root@oldgirl ~]# seq 10|awk '{i=i+$0;print i}'

1 i=i+$0 i=0 $0=1 i=0+1 -- 1 1

2 i=i+$0 i=1 $0=2 i=1+2 -- 3 3

3 i=i+$0 i=3 $0=3 i=3+3 -- 6 6

4 10

5 15

6 21

7 28

8 36

9 45

10 55


  [root@mysql-141 ~]# seq 10|awk '{i=i+$0;print i}'

    1

    3

    6

    10

    15

    21

    28

    36

    45

    55



    3). 數組的表現形式????????

        數組中的括號里面的內容


        hotel[元素01]=xiaolizi1? --- 調用print xiaolizi1[元素01]--- xiaolizi1

        hotel[元素02]=xiaolizi2 --- 調用print xiaolizi2[元素02]--- xiaolizi2


      數組統(tǒng)計命令組成說明:

      1) 找出要統(tǒng)計的信息

        $1


      2) 把指定要統(tǒng)計信息作為數組的元素

        h[$1]


      3) 利用統(tǒng)計運算公式,進行運算

        h[$1]=h[$1]+1 --- i=i+1


      4) 顯示運算的結果信息

        a 只看某一個元素的結果信息


     awk '{h[$1]=h[$1]+1}END{print h["101.226.61.184"]}' access.log

     5

        b 要看全部元素的結果信息


     awk '{h[$1]=h[$1]+1}END{print h["101.226.61.184"],h["114.94.29.165"]}' access.log

# 精簡后命令

      awk '{h[$1]++}END{for(name in h)print name,h[name]}' access.log




    for name in 101.226.61.184 114.94.29.165

      print h[$name]


      ==>

    for(name in h) --- > echo name=h=第一個元素信息

    echo name=h=第二個元素信息????????


說明: 循環(huán)中讀取數組名稱==讀取每一個元素名稱信息



cat >>url.txt<<EOF

http://www.etiantian.org/index.html

http://www.etiantian.org/1.html

http://post.etiantian.org/index.html

http://mp3.etiantian.org/index.html

http://www.etiantian.org/3.html

http://post.etiantian.org/2.html

EOF

awk '{h[$1]++}END{for(name in h)print name,h[name]}' access.log


[root@mysql-141 ~]# awk '{h[$1]++}END{for(name in h)print name,h[name]}' access.log

101.226.61.184 5

27.154.190.158 2

218.79.64.76 2

114.94.29.165 1



第一步: 定義數組信息

awk '{h[$1]}' access.log

說明: 數組中的元素就是你關注要統(tǒng)計的列的信息


第二步: 進行統(tǒng)計運算,編寫公式

awk '{h[$1]=h[$1]+1}' access.log


第三步: 編寫元素循環(huán)信息

awk '{h[$1]=h[$1]+1}END{for(name in h)}' access.log


第四步: 輸出結果信息???

awk '{h[$1]=h[$1]+1}END{for(name in h) print name,h[name]}' access.log

復制代碼

?將文本內容格式化輸出

  原文如下:


job_name??? job_group

syncCommStockJob??? dataSync

syncStoreChnlJob??? dataSync

syncOrderJob??? dataSync

syncReportStoreJob??? dataSync

hdfsScanJob??? report

orderSaleDailyJob??? report

jdzmdOrdersJob??? report

jdCanJob??? report


  使用awk格式化輸出后


cat xxx.txt | awk '{printf "%-30s%-15s\n",$1,$2}'??????????????

      #%-30s表示輸出字符串,寬度30位(字符串如果過長宫仗,可以自己調整),左對齊.%-15s用來指定第二列的,左對齊,寬度15.兩個百分號之間可以沒有空格.使用\n對每一行的輸出加上換行符



job_name????????????????????? job_group?????

syncCommStockJob????????????? dataSync??????

syncStoreChnlJob????????????? dataSync??????

syncOrderJob????????????????? dataSync??????

syncReportStoreJob??????????? dataSync??????

hdfsScanJob?????????????????? report? ? ? ? ? ? ? ? ? ? ? ? ?

轉自嘉為教育-rhce認證_rhce培訓_linux培訓_linux認證_linux考證

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末够挂,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子藕夫,更是在濱河造成了極大的恐慌孽糖,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件毅贮,死亡現場離奇詭異办悟,居然都是意外死亡,警方通過查閱死者的電腦和手機滩褥,發(fā)現死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門病蛉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瑰煎,你說我怎么就攤上這事铺然。” “怎么了酒甸?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵魄健,是天一觀的道長。 經常有香客問我插勤,道長沽瘦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任农尖,我火速辦了婚禮析恋,結果婚禮上,老公的妹妹穿的比我還像新娘盛卡。我一直安慰自己助隧,他們只是感情好,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布滑沧。 她就那樣靜靜地躺著并村,像睡著了一般漏健。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上橘霎,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音殖属,去河邊找鬼姐叁。 笑死,一個胖子當著我的面吹牛洗显,可吹牛的內容都是我干的外潜。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼挠唆,長吁一口氣:“原來是場噩夢啊……” “哼处窥!你這毒婦竟也來了?” 一聲冷哼從身側響起玄组,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤滔驾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后俄讹,有當地人在樹林里發(fā)現了一具尸體哆致,經...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年患膛,在試婚紗的時候發(fā)現自己被綠了摊阀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡踪蹬,死狀恐怖胞此,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情跃捣,我是刑警寧澤漱牵,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站枝缔,受9級特大地震影響布疙,放射性物質發(fā)生泄漏。R本人自食惡果不足惜愿卸,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一灵临、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧趴荸,春花似錦儒溉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽波闹。三九已至,卻和暖如春涛碑,著一層夾襖步出監(jiān)牢的瞬間精堕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工蒲障, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留歹篓,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓揉阎,卻偏偏與公主長得像庄撮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子毙籽,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內容