自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

awk中的字段、記錄和變量

系統(tǒng) Linux
Awk 有好幾個(gè)變種:最早的 awk,是 1977 年 AT&T 貝爾實(shí)驗(yàn)室所創(chuàng)。它還有一些重構(gòu)版本,例如 mawk、nawk。在大多數(shù) Linux 發(fā)行版中能見到的,是 GNU awk,也叫 gawk。在大多數(shù) Linux 發(fā)行版中,awk 和 gawk 都是指向 GNU awk 的軟鏈接。

[[283700]]

這個(gè)系列的第二篇,我們會(huì)學(xué)習(xí)字段,記錄和一些非常有用的 Awk 變量。

Awk 有好幾個(gè)變種:最早的 awk,是 1977 年 AT&T 貝爾實(shí)驗(yàn)室所創(chuàng)。它還有一些重構(gòu)版本,例如 mawknawk。在大多數(shù) Linux 發(fā)行版中能見到的,是 GNU awk,也叫 gawk。在大多數(shù) Linux 發(fā)行版中,awkgawk 都是指向 GNU awk 的軟鏈接。輸入 awk,調(diào)用的是同一個(gè)命令。GNU awk 用戶手冊(cè)中,能看到 awkgawk 的全部歷史。

這一系列的第一篇文章 介紹了 awk 命令的基本格式:

  1. $ awk [選項(xiàng)] '模式 {動(dòng)作}' 輸入文件

awk 是一個(gè)命令,后面要接選項(xiàng) (比如用 -F 來定義字段分隔符)。想讓 awk 執(zhí)行的部分需要寫在兩個(gè)單引號(hào)之間,至少在終端中需要這么做。在 awk 命令中,為了進(jìn)一步強(qiáng)調(diào)你想要執(zhí)行的部分,可以用 -e 選項(xiàng)來突出顯示(但這不是必須的):

  1. $ awk -F, -e '{print $2;}' colours.txt
  2. yellow
  3. blue
  4. green
  5. [...]

記錄和字段

awk 將輸入數(shù)據(jù)視為一系列記錄,通常是按行分割的。換句話說,awk 將文本中的每一行視作一個(gè)記錄。每一記錄包含多個(gè)字段。一個(gè)字段由字段分隔符分隔開來,字段是記錄的一部分。

默認(rèn)情況下,awk 將各種空白符,如空格、制表符、換行符等視為分隔符。值得注意的是,在 awk 中,多個(gè)空格將被視為一個(gè)分隔符。所以下面這行文本有兩個(gè)字段:

  1. raspberry red

這行也是:

  1. tuxedo                  black

其他分隔符,在程序中不是這么處理的。假設(shè)字段分隔符是逗號(hào),如下所示的記錄,就有三個(gè)字段。其中一個(gè)字段可能會(huì)是 0 個(gè)字節(jié)(假設(shè)這一字段中不包含隱藏字符)

  1. a,,b

awk 程序

awk 命令的程序部分是由一系列規(guī)則組成的。通常來說,程序中每個(gè)規(guī)則占一行(盡管這不是必須的)。每個(gè)規(guī)則由一個(gè)模式,或一個(gè)或多個(gè)動(dòng)作組成:

  1. 模式 { 動(dòng)作 }

在一個(gè)規(guī)則中,你可以通過定義模式,來確定動(dòng)作是否會(huì)在記錄中執(zhí)行。模式可以是簡(jiǎn)單的比較條件、正則表達(dá)式,甚至兩者結(jié)合等等。

這個(gè)例子中,程序只會(huì)顯示包含單詞 “raspberry” 的記錄:

  1. $ awk '/raspberry/ { print $0 }' colours.txt
  2. raspberry red 99

如果沒有文本符合模式,該動(dòng)作將會(huì)應(yīng)用到所有記錄上。

并且,在一條規(guī)則只包含模式時(shí),相當(dāng)于對(duì)整個(gè)記錄執(zhí)行 { print },全部打印出來。

Awk 程序本質(zhì)上是數(shù)據(jù)驅(qū)動(dòng)的,命令執(zhí)行結(jié)果取決于數(shù)據(jù)。所以,與其他編程語言中的程序相比,它還是有些區(qū)別的。

NF 變量

每個(gè)字段都有指定變量,但針對(duì)字段和記錄,也存在一些特殊變量。NF 變量,能存儲(chǔ) awk 在當(dāng)前記錄中找到的字段數(shù)量。其內(nèi)容可在屏幕上顯示,也可用于測(cè)試。下面例子中的數(shù)據(jù),來自上篇文章文本

  1. $ awk '{ print $0 " (" NF ")" }' colours.txt
  2. name       color  amount (3)
  3. apple      red    4 (3)
  4. banana     yellow 6 (3)
  5. [...]

awkprint 函數(shù)會(huì)接受一系列參數(shù)(可以是變量或者字符串),并將它們拼接起來。這就是為什么在這個(gè)例子里,每行結(jié)尾處,awk 會(huì)以一個(gè)被括號(hào)括起來的整數(shù)表示字段數(shù)量。

NR 變量

另外,除了統(tǒng)計(jì)每個(gè)記錄中的字段數(shù),awk 也統(tǒng)計(jì)輸入記錄數(shù)。記錄數(shù)被存儲(chǔ)在變量 NR 中,它的使用方法和其他變量沒有任何區(qū)別。例如,為了在每一行開頭顯示行號(hào):

  1. $ awk '{ print NR ": " $0 }' colours.txt
  2. 1: name       color  amount
  3. 2: apple      red    4
  4. 3: banana     yellow 6
  5. 4: raspberry  red    3
  6. 5: grape      purple 10
  7. [...]

注意,寫這個(gè)命令時(shí)可以不在 print 后的多個(gè)參數(shù)間添加空格,盡管這樣會(huì)降低可讀性:

  1. $ awk '{print NR": "$0}' colours.txt

printf() 函數(shù)

為了讓輸出結(jié)果時(shí)格式更靈活,你可以使用 awkprintf() 函數(shù)。 它與 C、Lua、Bash 和其他語言中的 printf 相類似。它也接受以逗號(hào)分隔的格式參數(shù)。參數(shù)列表需要寫在括號(hào)里。

  1. $ printf 格式, 項(xiàng)目1, 項(xiàng)目2, ...

格式這一參數(shù)(也叫格式符)定義了其他參數(shù)如何顯示。這一功能是用格式修飾符實(shí)現(xiàn)的。%s 輸出字符,%d 輸出十進(jìn)制數(shù)字。下面的 printf 語句,會(huì)在括號(hào)內(nèi)顯示字段數(shù)量:

  1. $ awk 'printf "%s (%d)\n",$0,NF}' colours.txt
  2. name       color  amount (3)
  3. raspberry  red    4 (3)
  4. banana     yellow 6 (3)
  5. [...]

在這個(gè)例子里,%s (%d) 確定了每一行的輸出格式,$0,NF 定義了插入 %s%d 位置的數(shù)據(jù)。注意,和 print 函數(shù)不同,在沒有明確指令時(shí),輸出不會(huì)轉(zhuǎn)到下一行。出現(xiàn)轉(zhuǎn)義字符 \n 時(shí)才會(huì)換行。

Awk 腳本編程

這篇文章中出現(xiàn)的所有 awk 代碼,都在 Bash 終端中執(zhí)行過。面對(duì)更復(fù)雜的程序,將命令放在文件(腳本)中會(huì)更容易。-f FILE 選項(xiàng)(不要和 -F 弄混了,那個(gè)選項(xiàng)用于字段分隔符),可用于指明包含可執(zhí)行程序的文件。

舉個(gè)例子,下面是一個(gè)簡(jiǎn)單的 awk 腳本。創(chuàng)建一個(gè)名為 example1.awk 的文件,包含以下內(nèi)容:

  1. /^a/ {print "A: " $0}
  2. /^b/ {print "B: " $0}

如果一個(gè)文件包含 awk 程序,那么在給文件命名時(shí),最好寫上 .awk 的擴(kuò)展名。 這樣命名不是強(qiáng)制的,但這么做,會(huì)給文件管理器、編輯器(和你)一個(gè)關(guān)于文件內(nèi)容的很有用的提示。

執(zhí)行這一腳本:

  1. $ awk -f example1.awk colours.txt
  2. A: raspberry  red    4
  3. B: banana     yellow 6
  4. A: apple      green  8

一個(gè)包含 awk 命令的文件,在最開頭一行加上釋伴 #!,就能變成可執(zhí)行腳本。創(chuàng)建一個(gè)名為 example2.awk 的文件,包含以下內(nèi)容:

  1. #!/usr/bin/awk -f
  2. #
  3. # 除了第一行,在其他行前顯示行號(hào)
  4. #
  5.  
  6. NR > 1 {
  7. printf "%d: %s\n",NR,$0
  8. }

可以說,腳本中只有一行,大多數(shù)情況下沒什么用。但在某些情況下,執(zhí)行一個(gè)腳本,比記住,然后打一條命令要容易的多。一個(gè)腳本文件,也提供了一個(gè)記錄命令具體作用的好機(jī)會(huì)。以 # 號(hào)開頭的行是注釋,awk 會(huì)忽略它們。

給文件可執(zhí)行權(quán)限:

  1. $ chmod u+x example2.awk

執(zhí)行腳本:

  1. $ ./example2.awk colours.txt
  2. 2: apple      red    4
  3. 2: banana     yellow 6
  4. 4: raspberry red    3
  5. 5: grape      purple 10
  6. [...]

awk 命令放在腳本文件中,有一個(gè)好處就是,修改和格式化輸出會(huì)更容易。在終端中,如果能用一行執(zhí)行多條 awk 命令,那么輸入多行,才能達(dá)到同樣效果,就顯得有些多余了。

試一試

你現(xiàn)在已經(jīng)足夠了解,awk 是如何執(zhí)行指令的了?,F(xiàn)在你應(yīng)該能編寫復(fù)雜的 awk 程序了。試著編寫一個(gè) awk 腳本,它需要: 至少包括一個(gè)條件模式,以及多個(gè)規(guī)則。如果你想使用除 printprintf 以外的函數(shù),可以參考在線 gawk 手冊(cè)。

下面這個(gè)例子是個(gè)很好的切入點(diǎn):

  1. #!/usr/bin/awk -f
  2. #
  3. # 顯示所有記錄 除了出現(xiàn)以下情況
  4. # 如果第一個(gè)記錄 包含 raspberry
  5. # red 替換成 pi
  6.  
  7. $1 == "raspberry" {
  8.         gsub(/red/,"pi")
  9. }
  10.  
  11. { print }

試著執(zhí)行這個(gè)腳本,看看輸出是什么。接下來就看你自己的了。

這一系列的下一篇文章,將會(huì)介紹更多,能在更復(fù)雜(更有用!) 腳本中使用的函數(shù)。 

 

責(zé)任編輯:龐桂玉 來源: Linux中國(guó)
相關(guān)推薦

2010-03-04 15:11:06

Ubuntu awk

2016-08-10 16:07:08

awkLinux開源

2016-08-11 09:18:33

awkShellLinux

2010-05-11 10:43:10

Unix awk

2016-08-10 11:19:11

awkLinux開源

2017-08-04 14:00:32

Linuxawk變量

2010-09-03 15:21:46

SQLselect語句

2024-11-06 17:04:47

AWK編程

2016-08-29 20:51:16

awkLinux開源

2010-05-11 13:16:21

Unix awk

2019-12-03 10:00:19

awkLinux循環(huán)

2011-03-29 13:22:07

SQL Server臨時(shí)表表變量

2023-12-10 21:35:45

Linux服務(wù)器日志分析

2019-12-12 18:00:54

awkLinux開源

2023-11-30 12:03:06

linuxAwk

2012-05-18 12:49:43

Android

2010-11-23 15:27:00

MySQL添加字段

2010-05-11 12:17:51

Unix awk

2023-10-26 15:49:53

Go日志

2013-07-31 11:09:05

C++11
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)