AWK 簡明教程 原 薦

AWK 腳本的結構

awk ' BEGIN{ print "start" } pattern { commands } END{ print "end" } file

awk 腳本通常由3部分組成。 BEGIN , END 和帶模式匹配選項的常見語句塊。這3個部分都是可 選項,在腳本中可省略任意部分。

AWK 腳本的執行

一、在命令行中執行 AWK 腳本

AWK 腳本包含在單引號之間

awk 'BEGIN { statements } { statements } END { end statements }'

二、把 AWK 腳本寫入文件

文件的內容格式如下

BEGIN { statements } { statements } END { end statements }

在命令使用如下命令執行腳本

awk -f <programfile> <inputfile>
  • programfile: AWK 腳本文件
  • inputfile: 被處理的文件

AWK 的工作方式

一、AWK工作流程圖

AWK工作流程圖

Read

AWK從輸入流(文件,管道或者標準輸入)中讀取一行,然後存儲到內存中。

Execute

所有的AWK命令都依次在輸入上執行。默認情況下,AWK會對每一行執行命令,我們可以通過提供模式限制這種行爲。

Repeat

處理過程不斷重複,直到到達文件結尾。

二、AWK 執行流程

  1. 執行 BEGIN { commands } 語句塊中的語句。
  2. 從文件或 stdin 中讀取一行,然後執行 pattern { commands } 。重複這個過程,直到文件全部被讀取完畢。
  3. 當讀至輸入流末尾時,執行 END { commands } 語句塊。

三、要點理解

  • BEGIN 語句塊在 awk 開始從輸入流中讀取行之前被執行。這是一個可選的語句塊,諸如變量 初始化、打印輸出表格的表頭等語句通常都可以寫入 BEGIN 語句塊中。
  • END 語句塊和 BEGIN 語句塊類似。 END 語句塊在 awk 從輸入流中讀取完所有的行之後即被執 行。像打印所有行的分析結果這類彙總信息,都是在 END 語句塊中實現的常見任務(例如,在比 較過所有的行之後,打印出最大數)。它也是一個可選的語句塊。
  • 最重要的部分就是 pattern 語句塊中的通用命令。這個語句塊同樣是可選的。如果不提供該 語句塊,則默認執行 { print } ,即打印所讀取到的每一行。 awk 對於每一行,都會執行這個語 句塊。這就像一個用來讀取行的 while 循環,在循環體中提供了相應的語句。
  • 每讀取一行, awk 就會檢查該行和提供的 pattern 是否匹配。pattern 本身可以是正則表達式、條件 語句以及行匹配範圍等。如果當前行匹配該 pattern ,則執行 { } 中的語句。
  • pattern 是可選的。如果沒有提供樣式,那麼 awk 就認爲所有的行都是匹配的,並執行 { } 中的 語句

AWK 的一些特殊變量

  • NR :表示記錄數量,在執行過程中對應於當前行號。

  • NF :表示字段數量,在執行過程中對應於當前行的字段數。

  • $0 :這個變量包含執行過程中當前行的文本內容。

  • $1 :這個變量包含第一個字段的文本內容。

  • $2 :這個變量包含第二個字段的文本內容。

  • $ awk '{ print $3,$2 }' file #打印每一行的第2和第3個字段:

  • $ awk 'END{ print NR }' file #統計文件中的行數

將外部變量值傳遞給 AWK

藉助選項 -v ,我們可以將外部值(並非來自 stdin )傳遞給 awk

$ VAR=10000
$ echo | awk -v VARIABLE=$VAR '{ print VARIABLE }'
10000

用 getline 讀取特定行:

awk 通常默認讀取一個文件的所有行。如果只想讀取某一行,可以使用 getline 函數。有時候,我們需要從 BEGIN 語句塊中讀取第一行。

語法: getline var 變量 var 就包含了特定行的內容。如果調用不帶參數的 getline ,我們可以用 $0$1$2 訪問文本行的內容。

$ seq 5 | awk 'BEGIN { getline; print "Read ahead first line", $0 } { print $0 }'
Read ahead first line 1
2
3
4
5

使用過濾模式對 AWK 處理的行進行過濾:

$ awk 'NR < 5'      # 行號小於5 的行
$ awk 'NR==1,NR==4'      # 行號在1 到5 之間的行
$ awk '/linux/'      # 包含樣式linux 的行(可以用正則表達式來指定模式)
$ awk '!/linux/'      # 不包含包含模式爲linux

設置字段定界符:

默認的字段定界符是空格。我們也可以用 -F "delimiter" 明確指定一個定界符

$ awk -F: '{ print $NF }' /etc/passwd

在 BEGIN 語句塊中則可以用 OFS="delimiter" 設置輸出字段的定界符。

從 AWK 中讀取命令輸出:

將命令的輸出結果讀入變量 output 的語法如下

"command" | getline output ;
$ echo | awk '{ "grep root /etc/passwd" | getline cmdout ; print cmdout }'
root:x:0:0:root:/root:/bin/bash

通過使用 getline ,我們將外部shell命令的輸出讀入變量 cmdout 。

在 AWK 中可以使用 for 循環,其格式如下:

for(i=0; i<10; i++) { print $i ; }
或者
for(i in array) { print array[i]; }

AWK 內建的字符串控制函數

  • length(string) :返回字符串的長度。
  • index(string, search_string) :返回 search_string 在字符串中出現的位置。
  • split(string, array, delimiter) :用定界符生成一個字符串列表,並將該列表存 入數組。
  • substr(string, start-position, end-position) :在字符串中用字符起止偏移 量生成子串,並返回該子串。
  • sub(regex, replacement_str, string) :將正則表達式匹配到的第一處內容替換 成 replacment_str 。
  • gsub(regex, replacment_str, string) :和 sub() 類似。不過該函數會替換正則表 達式匹配到的所有內容。
  • match(regex, string) :檢查正則表達式是否能夠匹配字符串。如果能夠匹配,返回 非0值;否則,返回0。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章