1. 程式人生 > >Shell指令碼之awk篇

Shell指令碼之awk篇

目錄:
一、概述
二、awk基本語法格式
三、awk基本操作
四、awk條件及迴圈語句
五、awk函式
六、awk演示示例(源自於man手冊)

一、概述


1. 產品概述:


    awk是一種程式語言,用於在linux/unix下對文字和資料進行掃描與處理。資料可以來自標準輸入、檔案、管道。
    awk分別代表其作者姓氏的第一個字母。因為它的作者是三個人,分別是Alfred Aho、Peter Weinberger、Brian Kernighan。
    實際上awk有很多種版本,如:awk、nawk、mawk、gawk、MKS awk、tawk...  這其中有開源產品也有商業產品。
    目前在Linux中常用的awk編譯器版本有mawk,gawk,其中以RedHat為代表使用的是gawk,以Ubuntu為代表使用的是mawk。
    gawk是GNU Project 的awk直譯器的開原始碼實現。
    本文將以gawk作為講解工具。

2. 原理:


    1). awk逐行掃描檔案,從第一行到最後一行,尋找匹配特定模式的行,並在這些行上進行你想要的操作。
    2). awk基本結構包括模式匹配(用於找到要處理的行)和處理過程(即處理動作)。
       pattern  {action}
# 提示:awk讀取檔案內容的每一行時,將對比改行是否與給定的模式相匹配,如果匹配則執行處理過程,否則對該行不做任何處理。
如果沒有指定處理指令碼,則把匹配的行顯示到標準輸出,即預設處理動作是print列印行;
如果沒有指定模式匹配,則預設匹配所有資料。

      3). awk有兩個特殊的模式:BEGIN和END,他們被放置在沒有讀取任何資料之前以及在所有資料讀取完成以後執行。

3. awk流程圖:

awk處理過程

  提示:awk將檔案中的每一行當作一條記錄,並將記錄分割為若干欄位,預設以空格或製表符為分隔符。

如This   is   a    test    file.    將分割為5個欄位,awk可以對這5個欄位進行分別處理。

二、awk基本語法格式


1. 格式:

gawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...

註釋:POSIX or GNU style options表示gawk支援POSIX以及GNU兩種選項;-f後接指令碼檔案;file表示準備處理的文件名稱。

2. gawk支援以下選項:


     -F fs
         --field-separator fs
     指定以fs作為輸入行的分隔符(預設分隔符為空格或製表符)
     -v var=val
         --assign var=val
     在執行處理過程以前,設定一個變數var值為val
     -f program-file
     --file program-file
    從指令碼檔案中讀取AWK指令,以取代在命令引數中輸入處理指令碼
    -W compat
    -W traditional
    --compat
    --traditional
    使用相容模式執行awk,GNU擴充套件選項將被忽略
    -W copyleft
        -W copyright
        --copyleft
        --copyright
    輸出簡短的GNU版權資訊
    -W dump-variables[=file]
        --dump-variables[=file]
    列印全域性變數(變數名、型別、值)到檔案中,如果沒有提供檔名,則自動輸出至名為dump-variables的檔案中。
    示例:
awk -W dump-variables=out.txt 'x=1 {print x}' test.txt

    -W exec file
    --exec file
    類似於-f選項,但指令碼檔案需要以#!開頭;另外命令列的變數將不再生效
    -W help
        -W usage
        --help
        --usage
    顯示各個選項的簡短描述

3. awk程式結構


    一個awk程式包含一系列的  模式 {動作指令} 或是函式定義。
    模式可以是:
    BEGIN
    END
    表示式
    表示式,表示式
    動作指令需要以{}引起來

4. 簡單示例:

   
awk '/^$/ {print "Blank line}' test.txt

    備註:/^$/通過正則表示式匹配空白行,動作為列印Blank line;即test.txt如有N個空白行,awk將在螢幕列印N個Blank line。

awk '/HOSTNAME/' /etc/sysconfig/network

    備註:列印包含主機名的行,因為沒有指定動作指令,預設動作為列印。

cat awk.sh
'/^$/ {print "Blank line}'
awk -f awk.sh test.txt

    備註:提前編輯一個awk指令碼再通過-f選項呼叫該指令碼。

三、awk基本操作


1. 記錄與欄位


    awk一次從檔案中讀取一條記錄,並將記錄儲存在欄位變數$0中。記錄被分割為欄位並存儲在$1,$2 ..., $NF中(預設使用空格或製表符為分隔符)。
    內建變數NF為記錄的欄位個數
    示例:
echo hello the world | awk '{print  $1,$2,$3}'

      備註:讀取輸入行並輸出第一個欄位,第二個欄位,第三個欄位。

echo hello the world | awk '{print  $0}'

    備註:讀取輸入行並輸出該行。

echo hello the world | awk '{print NF}'

    備註:讀取輸入行並輸出該行的欄位個數:3個欄位。 

echo hello the world | awk '{print $NF}'

    備註:讀取輸入行並輸出該行的第三個欄位,因為NF為3,所以$NF等同於取行的最後一個欄位。

2. 欄位分隔符


    預設awk讀取資料以空格或製表符作為分隔符,但可以通過-F或FS(field separator)變數來改變分隔符。
    示例:
awk -F: '{print $1}' /etc/passwd
awk 'BEGIN {FS = ":"} {print $1}' /etc/passwd

    備註:以上兩個示例均將欄位的分隔符改冒號(:),即以冒號為分隔符列印passwd檔案的第一個欄位(帳號名稱)。
    注意:如果使用FS改變分隔符的話,需要在BEGIN處定義FS,因為在讀取第一行前就需要改變欄位分隔符。
    進階:指定多個欄位分隔符(文件內容為:hello the:word,!)

echo 'hello the:word,!' | awk 'BEGIN {FS="[:, ]"} {print $1,$2,$3,$4}'

3. 內建變數


    以下為awk內建變數:
          ARGC        命令列引數個數
          FILENAME    當前輸入文件的名稱
          FNR        當前輸入文件的當前記錄編號,尤其當有多個輸入文件時有用
          NR        輸入流的當前記錄編號
          NF        當前記錄的欄位個數
          FS        欄位分隔符
          OFS        輸出欄位分隔符,預設為空格
          ORS        輸出記錄分隔符,預設為換行符\n
          RS        輸入記錄分隔符,預設為換行符\n
    示例:
cat test1.txt
This is a test file. 
Welcome to Jacob's Class.
cat test2.txt
Hello the world. 
Wow! I'm overwhelmed. 
Ask for more. 
   輸出當前文件的當前行編號,第一個檔案兩行,第二個檔案三行:
awk '{print FNR}' test1.txt test2.txt
1
2
1
2
3
   awk將兩個文件作為一個整體的輸入流,通過NR輸入當前行編號:
awk '{print NR}' test1.txt test2.txt
1
2
3
4
5

    test1.txt文件的第一行有5個欄位,第二行有4個欄位:

awk '{print NF}' test1.txt
5
4
awk 'BEGIN {FS = ":"} {print $1}' /etc/passwd
awk '{print $1,$2,$3}' test1.txt

    備註:預設print輸出時,各引數將的輸出分隔符預設為空格,所以輸出內容如下。

This is a
Welcome to Jacob's
awk 'BEGIN {OFS="-"} {print $1,$2,$3}' test1.txt

    備註:通過OFS將輸出分隔符設定為"-",這個print在輸出第一、二、三個欄位時,中間的分隔符為"-",結果如下:

This-is-a
Welcome-to-Jacob's
cat test3.txt
  mail from: [email protected] 
  subject:hello 
  date:2012-07-12 17:00 
  content:Hello, The world.

  mail from: [email protected] 
  subject:congregation 
  date:2012-07-12 08:31 
  content:Congregation to you.  

  mail from: [email protected] 
  subject:Test 
  date:2012-07-12 10:20 
  content:This is a test mail.
awk 'BEGIN {FS="\n"; RS=""} {print $3}' test3.txt

      備註:讀取輸入資料,以空白行為記錄分隔符,即第一個空白行前的內容為第一個記錄,第一個記錄中欄位分隔符為換行符。
    以上awk的效果為列印所有的郵件時間,即每個記錄的第三個欄位。

4. 表示式與操作符


    表示式是由變數、常量、函式、正則表示式、操作符組成,awk中變數有字元變數和數字變數。如果在awk中定義的變數沒有初始化,則初始值為空字串或0。
    注意:字元操作時一定記得需要加引號
    1) 變數定義示例:
   a="welcome to beijing"
   b=12

    2) 操作符(awk操作符與C語言類似)
    +        加
    -        減
    *        乘
    /        除
    %        取餘
    ^        冪運算
    ++        自加1
    --        自減1
    +=        相加後賦值給變數(x+=9等同於x=x+9)
    -=        相減後賦值給變數(x-=9等同於x=x-9)
    *=        相乘後賦值給變數(x*=9等同於x=x*9)
    /=        相除後賦值給變數(x/=9等同於x=x/9)
    >        大於
    <        小於
    >=        大於等於
    <=        小於等於
    ==        等於
    !=        不等於
    ~        匹配
    !~        不匹配
    &&        與
    ||        或
    操作符簡單示例:

echo "test" | awk 'x=2 {print x+3}'
echo "test" | awk 'x=2,y=3 {print x*2, y*3}'
   統計所有空白行:
awk '/^$/ {print x+=1}' test.txt
   列印總空白行個數:
awk '/^$/ {x+=1} END {print x}' test.txt
   列印root的ID號:
awk -F: '$1~/root/ {print $3}' /etc/passwd
   列出計算機中ID號大於500的使用者名稱:
awk -F: '$3>500 {print $1}' /etc/passwd

四、awk條件及迴圈語句


   

1. IF條件判斷格式:


    if (表示式)
        動作1
    else
        動作2
    或者if (表示式)  動作1;else 動作2
    說明:如果表示式的判斷結果為真則執行動作1,否則執行動作2。
    示例:(判斷boot分割槽可用容量小於20M時報警,否則顯示OK)
df | grep "boot" | awk '{if($4<20000) print "Alart"; else print "OK"}'

2. 迴圈

    while (條件)
        動作
    x=1
    while (i < 10) {
        print $i
    }

    示例:

awk 'i=1 {} BEGIN { while (i<=10) {++i; print i}}' test.txt
    do
        動作
    while (條件)

    示例:

awk 'BEGIN { do {++x;print x} while (x<=10)}' test.txt

    for (變數;條件;計數器)
        動作
    示例:
    for (i=1;i<=10;i++)
        print i

awk 'BEGIN {for(i=1;i<=10;i++) print i}' test.txt
awk 'BEGIN {for(i=10;i>=1;i--) print i}' test.txt

    說明:因為以上迴圈語句使用的awk均使用的BEGIN模式,所以輸入文件可以為任意文件(無關緊要)。

   

3. Break與Continue


    break        跳出迴圈
    continue    終止當前迴圈
    示例:
    for  (i=1; i<=10;i++) {
        if (i=5)
            continue
        print i
    }

    說明:列印1-4,6-10

    for  (i=1; i<=10;i++) {
        if (i=5)
            break
        print i
    }

    說明:僅列印1-4

五、函式


    1. rand ()        產生0-1之間的浮動型別的隨機數
    備註:rand產生隨機數時需要通過srand()設定一個引數,否則單獨的rand()每次刪除的隨機數都是一樣的。
    示例:
awk 'BEGIN {print rand(); srand(); print srand()}' test.txt

2. gsub(x,y,z)

        在字串z中使用字串y替換與正則表示式x相匹配的所有字串,z預設為$0
        sub(x,y,z)        在字串z中使用字串y替換與正則表示式x相匹配的第一個字串,z預設為$0
    示例:

   將passwd每行中所有的root修改為jacob顯示至螢幕

awk -F: 'gsub(/root/,"jacob",$0) {print $0}' /etc/passwd

   將passwd每行中第一個root修改為jacob顯示至螢幕

awk -F: 'sub(/root/,"jacob",$0) {print $0}' /etc/passwd

    sub相當於sed中的s///,gsub相當於sed中的s///g。
   

3. length(z)

        返回字串z的長度
    示例:顯示test.txt文件每行的字元長度
awk '{print length()}' test.txt

4. gentline

        從輸入中讀取下一行內容
    示例:
df -h
  1. Filesystem            Size  Used Avail Use% Mounted on 
  2. /dev/mapper/VolGroup00-LogVol00 
  3.                        19G  3.6G   15G  21% / 
  4. /dev/sda1              99M   14M   81M  15% /boot 
  5. tmpfs                 141M     0  141M   0% /dev/shm 
  6. none                  140M  104K  140M   1% /var/lib/xenstored 
  說明:從以上命令的輸出結果可以看出,分割槽的剩餘容量顯示在第4列,但唯獨/根分割槽的記錄顯示在了兩行;我們需要判斷當記錄的欄位個數為1時,讀取下一行,並將該行的第3列顯示至螢幕。
df -h | awk '{if(NF==1) {getline; print $3}; if(NF==6) print $4}'
df -h | awk 'BEGIN {print "Disk Free:"} {if(NF==1) {getline; print $3}; if(NF==6) print $4}'

六、awk演示示例(源自於man手冊)


      

1. emulate cat:模擬cat程式

     { print }

2. emulate wc:模擬wc程式,統計行數、單詞數、字元數

     { chars += length($0) + 1  # add one for the \n
        words += NF
     }
     END{ print NR, words, chars }

3. sum the second field of every record based on the first field.        根據第一列的內容統計第二列的資料

     $1 ~ /credit|gain/ { sum += $2 }
     $1 ~ /debit|loss/  { sum -= $2 }
     END { print sum }

4. Print and sort the login names of all users:                顯示計算機帳號使用者名稱並排序

     BEGIN { FS = ":" }
     { print $1 | "sort" }

相關推薦

Shell指令碼awk

目錄: 一、概述 二、awk基本語法格式 三、awk基本操作 四、awk條件及迴圈語句 五、awk函式 六、awk演示示例(源自於man手冊) 一、概述 1. 產品概述:     awk是一種程式語言,用於在linux/unix下對文字和資料進行掃描與處理。資料可以來自

shell指令碼awk

(一) 什麼是awk awk其實相當於一門可以處理資料文字的語言,這麼說的原因是其具有很多類c語言的語法,如:變數,陣列,函式,流程控制等,其由Aho,Weinberger,Kernighan大約在1977年開發完成,隨後被引入unix/linux中。

shell指令碼正則表示式、函式、grep、sed、awk、printf等基本命令配置詳解

一、正則表示式 簡介: 正則表示式(或稱Regular Expression,簡稱RE)就是由普通字元(例如字元 a 到 z)以及特殊字元(稱為元字元)組成的文字模式。該模式描述在查詢文字主體時待匹配的一個或多個字串。正則表示式作為一個模板,將某個字元模式與所搜尋的字串進

shell指令碼awk和sed

awk 和sed     cut [選項] 檔名   預設分隔符是製表符     選項:         -f 列號:    提取第幾列 &

[一天幾個linux命令] shell指令碼正則表示式

shell指令碼之正則表示式 原文連結:Linux–shell指令碼之正則表示式 概念及特點 概念 正則表示式是對字串操作的一種邏輯公式,就是用事先定義好的一些特定的字元、及這些特定字元的組合,組成一個"規則字串",這個"規則字串"用來表達對字串的一種過濾邏輯。規定一些特殊語

Linux Shell指令碼程式設計 --awk命令詳解

簡單使用: awk :對於檔案中一行行的獨處來執行操作 。 awk -F :'{print $1,$4}'   :使用‘:’來分割這一行,把這一行的第一第四個域打印出來 。    

shell學習awk或gawk

AWK 是該程式語言本身的名稱,它編寫於 1977 年。其名稱是三個主要作者的姓的首字母縮寫:Drs. A. Aho、P. Weinberger 和 B. Kernighan。 因為 AWK 是一種文字處理和模式匹配語言,所以它通常稱為資料驅動的語言,程式語句描述需要進行匹配和處理的輸

shell指令碼 對於 非ssh expect 免密登陸問題

背景:一般為了安全hadoop生產叢集與公司其他伺服器不能ping,不能互相ssh免密登入的。絕大多數是hadoop叢集伺服器可以有賬號密碼可以登入到其他伺服器,但其他伺服器,不可以登入到公司hadoop叢集伺服器。業務需要 從一臺非業務伺服器上scp拉取資料,這時用到 expect遠端登入

Shell指令碼等腰三角形

指令碼內容: #!/bin/bash # 等腰三角形 read -p "Please input the length: " n #請輸入長度: for i in `seq 1 $n` do for ((j=$n;j>i;j--)) do

Shell指令碼俄羅斯方塊

指令碼內容: #!/bin/bash # Tetris Game # 10.21.2003 xhchen<[email][email protected][/email]> #APP declaration APP_NAME="${0##*[\\/]}"

Shell指令碼for語句

在shell語句中的for有兩種的格式,具體的使用help  for 命令來檢視幫助    for迴圈語句的主要的格式有: 格式一:   for  x  in   do  command  do

Shell指令碼while 語句

在shell指令碼中的while語句在linux上的使用help  while來檢視其基本的用法    從圖上可以看出while語句的基本格式是    while   command   ; do  co

shell指令碼基礎

Linux之shell指令碼 Shell就是一個命令列直譯器,它的作用就是遵循一定的語法將輸入的命令加以解釋並傳給系統。開啟文字編輯器(可以使用vi/vim命令來建立檔案),新建一個檔案test.sh,副檔名為sh(sh代表shell)。

2.shell指令碼變數

1.變數命名法則 1、不能使程式中的保留字:例如if, for 2、只能使用數字、字母及下劃線,且不能以數字開頭 3、見名知義 4、統一命名規則:駝峰命名法 5、=前後不要帶空格 6、字串建議加" " :如name=“chenjuxni” 變數引用: 語法:$

shell三劍客awk 資料擷取工具 詳解

目錄 awk 資料擷取工具 ③變數 ④流程控制 ⑤陣列 ⑥內建函式 ①awk簡介 >>>awk是一種程式語言(解釋性語言,不需要編譯),用於資料擷取和報告的工具 >>>awk自動搜尋輸入的檔案

shell 指令碼切換使用者

                用su - 使用者 -c 命令格式來執行. 有時候需要切換到root使用者做一些操作,如果你的使用者沒有新增sudo許可權,那麼在指令碼中實現就需要使用expect命令了,具體實現如下:#!/usr/bin/expectspawn su rootexpect "Passwo

shell指令碼批量修改副檔名

指令碼內容如下(帶#的行不會執行,是批註): #!/bin/bash #執行指令碼時,需要給指令碼新增位置引數 #指令碼名 txt doc(可以將 txt 的副檔名修改為 doc) #指令碼名 doc jpg(可以把 doc 的副檔名修改為 jpg) for i

shell指令碼九九乘法表

指令碼內容: #!/bin/bash for i in seq 9 do for j in seq $i do echo -n “i∗i*i∗j=$[j*i]” done echo done

shell指令碼字串操作

1.取字元長度 var="abcdef" echo ${#var} echo ${var} | awk '{print length($0)}' echo ${var} | awk -F "" '{print NF}' echo `expr length ${v

shell指令碼函式(八)

#簡單呼叫函式的例子 demoFun(){ echo "這是我的第一個shell函式" } echo "開始測試函式呼叫" demoFun 下面定義一個帶有return語句的函式: #!/bin/bash # author:菜鳥教程 # url:www.ru