當(dāng)前位置:首頁 > IT技術(shù) > 系統(tǒng)服務(wù) > 正文

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)
2021-09-28 16:51:05

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_linux

?開篇語:

在 Linux 命令中,??awk???是一個處理文件中的數(shù)據(jù)的高級工具,它能提供一個類編程環(huán)境來修改和重新組織文件中的數(shù)據(jù)。

特別說明:

?GNU gawk

??awk???既是一個命令,也是一種程序語言,它可以有不同的實現(xiàn)版本。

在 Linux 系統(tǒng)中,??awk???的實現(xiàn)版本是 GNU gawk。在 shell 中執(zhí)行???awk???命令,實際執(zhí)行的是???gawk???命令。

如此截圖:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_linux_02

?所以下文中所說的gawk也就是我們常稱呼的awk。

一、初始gawk

gawk 程序讓流編輯邁上了一個新的臺階,它提供了一種編程語言而不只是編輯器命令。

gawk 功能概述:

  1. 定義變量來保存數(shù)據(jù);
  2. 使用算術(shù)和字符串操作符來處理數(shù)據(jù);
  3. 使用結(jié)構(gòu)化編程概念(比如if-then語句和循環(huán))來為數(shù)據(jù)處理增加處理邏輯;
  4. 通過提取數(shù)據(jù)文件中的數(shù)據(jù)元素,將其重新排列或格式化,生成格式化報告。

1.1 gawk 的命令格式?

?gawk的命令格式:

gawk options program file

參數(shù)選項:

  • -F fs? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 指定行中劃分?jǐn)?shù)據(jù)字段的字段分隔符
  • -f file? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 從指定的文件中讀取程序
  • -v var=value? ? ? ? ? ? ? ? ? 定義gawk程序中的一個變量及其默認(rèn)值
  • -mf N? ? ? ? ? ? ? ? ? ? ? ? ? ? ?指定要處理的數(shù)據(jù)文件中的最大字段數(shù)
  • -mr N? ? ? ? ? ? ? ? ? ? ? ? ? ? ?指定數(shù)據(jù)文件中的最大數(shù)據(jù)行數(shù)
  • -W keyword? ? ? ? ? ? ? ? ? ?指定gawk的兼容模式或警告等級

實戰(zhàn)說明:

命令行選項提供了一個簡單的途徑來定制 gawk 程序中的功能。我們會在探索 gawk 時進(jìn)一步

了解這些選項。

gawk 的強(qiáng)大之處在于程序腳本??梢詫懩_本來讀取文本行的數(shù)據(jù),然后處理并顯示數(shù)據(jù),創(chuàng)

建任何類型的輸出報告。

1.2 從命令行讀取程序腳本

gawk程序腳本用一對花括號來定義。你必須將腳本命令放到兩個花括號{}中。由于gawk命令行假定腳本是單個文本字符串,還必須將腳本命令放到單引號中。

簡單的示例:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_linux_03

?命令解說:

? ? ?如果你操作這個示例在你的服務(wù)器終端,你會發(fā)現(xiàn),并沒有任何結(jié)果輸出,而當(dāng)你隨意輸入一個數(shù)字或者字符串的時候會發(fā)現(xiàn)都會返回 同一個結(jié)果,這個原因就在于沒有在命令行上指 定文件名,所以gawk程序會從STDIN接收數(shù)據(jù)。在運(yùn)行這個程序時,它會一直等待從STDIN輸入 的文本。 如果你輸入一行文本并按下回車鍵,gawk會對這行文本運(yùn)行一遍程序腳本。和??sed??編輯器一 樣,gawk程序會針對數(shù)據(jù)流中的每行文本執(zhí)行程序腳本。由于程序腳本被設(shè)為顯示一行固定的文 本字符串,因此不管你在數(shù)據(jù)流中輸入什么文本,都會得到同樣的文本輸出。

1.3 使用數(shù)據(jù)字段變量

gawk 的主要特性之一是其處理文本文件中數(shù)據(jù)的能力。它會自動給一行中的每個數(shù)據(jù)元素分

配一個變量。默認(rèn)情況下, gawk會將如下變量分配給它在文本行中發(fā)現(xiàn)的數(shù)據(jù)字段,而且在文本行中,每個數(shù)據(jù)字段都是通過字段分隔符劃分的。gawk在讀取一行文本時,會用預(yù)定義的字段分隔符劃分每個數(shù)據(jù)字段。gawk中默認(rèn)的字段分隔符是任意的空白字符。

數(shù)據(jù)字段釋義:

  • $0代表整個文本行;
  • $1代表文本行中的第1個數(shù)據(jù)字段;
  • $2代表文本行中的第2個數(shù)據(jù)字段;
  • $n代表文本行中的第n個數(shù)據(jù)字段。

操作示例:

a.顯示第1個數(shù)據(jù)字段的值

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_awk_04?

1.4 在腳本程序中使用多個命令

gawk 編程語言支持將多條 命令組合成一個正常的程序。要在命令行上的程序腳本中使用多條命令,只要在命令之間放個分號即可。

操作示例:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_linux_05?

?命令詳解:

第一條命令會給字段變量 $4 賦值。第二條命令會打印整個數(shù)據(jù)字段。注意, gawk 程序在輸

出中已經(jīng)將原文本中的第四個數(shù)據(jù)字段替換成了新值。

?1.5?從文件中讀取程序

gawk編輯器支持將程序存儲到文件中,然后再在命令行中引用。

a 操作示例:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_awk_06?

?命令詳解:

應(yīng)用腳本文件只需要使用 -f 參數(shù)即可,此示例程序腳本會使用print命令輸出/etc/passwd文件的主目錄數(shù)據(jù)字段(字段變 量$6),以及userid數(shù)據(jù)字段(字段變量$1)。

程序文件中也可以指定多條命令。只需要一條命令放一行即可,不需要用分號。

b操作示例:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_基礎(chǔ)運(yùn)維_07?

1.6 處理數(shù)據(jù)前運(yùn)行腳本

gawk 允許指定程序腳本何時運(yùn)行。默認(rèn)情況下, gawk 會從輸入中讀取一行文本,然后針對該行的數(shù)據(jù)執(zhí)行程序腳本。有時可能需要在處理數(shù)據(jù)前運(yùn)行腳本,此時需要用到關(guān)鍵字BEGIN ,它會強(qiáng)制gawk 在讀取數(shù)據(jù)前執(zhí)行 BEGIN 關(guān)鍵字后指定的程序腳本。

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_linux_08?

可以看到此時我們沒有輸入文本內(nèi)容同樣可以輸出內(nèi)容,當(dāng)然這種單一的使用是不常用的,工作中我們常常是結(jié)合其他命令,此時的名利格式是這樣的:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_大數(shù)據(jù)_09??命令解說:

此時我們在BEGIN腳本區(qū)域后用 { } 定義一個新的腳本區(qū)域,這個腳本區(qū)域的程序會相繼執(zhí)行。值得注意的是,不管后面有幾個腳本區(qū)域,他們都需要包含在同一個單引號之中。

?1.7 在處理數(shù)據(jù)后運(yùn)行腳本

與BEGIN對應(yīng),END關(guān)鍵字允許指定一個程序腳本,gawk會在讀完數(shù)據(jù)后執(zhí)行它。

演示截圖:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_大數(shù)據(jù)_10?

?命令解說:

當(dāng) gawk 程序輸出完文件所有內(nèi)容后,執(zhí)行 END 腳本中的命令。

?小小趣味實戰(zhàn):

腳本內(nèi)容:

BEGIN { 
print "The latest list of users and shells"
print " UserID Shell"
print "-------- -------"
FS=":"
}
{
print $1 " " $7
}
END {
print "This concludes the listing"
}

演示截圖(結(jié)尾部分有做刪節(jié))?

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_大數(shù)據(jù)_11?

?說明:

這個腳本定義了一個叫作FS的特殊變量。這是定義 字段分隔符的另一種方法。這樣你就不用依靠腳本用戶在命令行選項中定義字段分隔符了。

二 、gawk 變量的使用

gawk支持兩種類型的變量:

  1. 內(nèi)建變量
  2. 自定義變量

2.1 gawk 內(nèi)建變量

gawk 程序使用內(nèi)建變量來引用程序數(shù)據(jù)里的一些特殊功能。

2.1.1?字段和記錄分隔符變量

數(shù)據(jù)字段變量:

引用記錄中的第一個數(shù)據(jù)字段,就用變量$1 ;要引用第二個字段,就用 $2 ,依次類推。

gawk命令可以在命令行下使用參數(shù) -F 或者在 gawk 程序中使用特殊的內(nèi)建變量FS 來更改字段分隔符。內(nèi)建變量FS是一組內(nèi)建變量中的一個,這組變量用于控制gawk如何處理輸入輸出數(shù)據(jù)中的

字段和記錄。如下是常用的一些內(nèi)置變量:



  • FIELDWIDTHS ? ? ? ? ? ? ?由空格分隔的一列數(shù)字,定義了每個數(shù)據(jù)字段確切寬度
  • FS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?輸入字段分隔符
  • RS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?輸入記錄分隔符
  • OFS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?輸出字段分隔符
  • ORS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??輸出記錄分隔符


A:核心說明

OFS和FS都 定義了 gawk如何處理數(shù)據(jù)流中的數(shù)據(jù)字段,區(qū)別在于,OFS是使用在 print命令的輸出上。默認(rèn)情況下, gawk 將OFS設(shè)成一個空格。

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_基礎(chǔ)運(yùn)維_12?

print 命令會自動將 OFS 變量的值放置在輸出中的每個字段間。通過設(shè)置 OFS 變量,可以在輸出中使用任意字符串來分隔字段。



一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_大數(shù)據(jù)_13



FIELDWIDTHS 變量允許你不依靠字段分隔符來讀取記錄。在一些應(yīng)用程序中,數(shù)據(jù)并沒有使用字段分隔符,而是被放置在了記錄中的特定列。這種情況下,必須設(shè)定FIELDWIDTHS 變量來匹配數(shù)據(jù)在記錄中的位置。

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_awk_14

?說明:

FIELDWIDTHS 變量定義了四個字段, gawk 依此來解析數(shù)據(jù)記錄。每個記錄中的數(shù)字串會根

據(jù)已定義好的字段長度來分割。

B:核心說明

變量 RS 和 ORS 定義了 gawk 程序如何處理數(shù)據(jù)流中的字段。默認(rèn)情況下, gawk 將 RS 和 ORS 設(shè)為換行符。默認(rèn)的RS 值表明,輸入數(shù)據(jù)流中的每行新文本就是一條新紀(jì)錄。

?示例截圖:一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_基礎(chǔ)運(yùn)維_15

?命令解說:

該示例中 把 FS變量設(shè)置成換行符。這就表明數(shù)據(jù)流中的每行都是一個單獨(dú)的字 段,每行上的所有數(shù)據(jù)都屬于同一個字段。把 RS 變量設(shè)置成空字符串,然后在數(shù)據(jù)記錄間留一個空白行。 gawk 會把每個空白行當(dāng)作一個記錄分隔符。

2.1.2 數(shù)據(jù)變量

常用變量如下:

  • ARGC ?? ??? ? 當(dāng)前命令行參數(shù)個數(shù)
  • ARGIND ?? ??? ? 當(dāng)前文件在ARGV中的位置
  • ARGV ?? ??? ? 包含命令行參數(shù)的數(shù)組
  • CONVFMT?? ??? ? 數(shù)字的轉(zhuǎn)換格式(參見printf語句),默認(rèn)值為%.6 g
  • ENVIRON ?? ? 當(dāng)前shell環(huán)境變量及其值組成的關(guān)聯(lián)數(shù)組
  • ERRNO ?? ??? ? 當(dāng)讀取或關(guān)閉輸入文件發(fā)生錯誤時的系統(tǒng)錯誤號
  • FILENAME ? ? 用作gawk輸入數(shù)據(jù)的數(shù)據(jù)文件的文件名
  • FNR ? ? ? ? ?當(dāng)前數(shù)據(jù)文件中的數(shù)據(jù)行數(shù)
  • IGNORECASE ? 設(shè)成非零值時,忽略gawk命令中出現(xiàn)的字符串的字符大小寫
  • NF ? ? ? ? ? 數(shù)據(jù)文件中的字段總數(shù)
  • NR ? ? ? ? ? 已處理的輸入記錄數(shù)
  • OFMT ? ? ? ? 數(shù)字的輸出格式,默認(rèn)值為%.6 g
  • RLENGTH ? ? ?由match函數(shù)所匹配的子字符串的長度
  • RSTART ? ? ? 由match函數(shù)所匹配的子字符串的起始位置

核心解說:

在上面的列表中有一些 shell 腳本編程中的變量。 ARGC 和 ARGV 變量允許從 shell 中獲得命令行參數(shù)的總數(shù)以及它們的值。但這可能有點(diǎn)麻煩,因為gawk 并不會將程序腳本當(dāng)成命令行參數(shù)的一部分。

操作示例:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_linux_16

說明:

?ARGC變量表明命令行上有兩個參數(shù)。這包括gawk命令和data1參數(shù)(記住,程序腳本并不算參數(shù))。ARGV數(shù)組從索引0開始,代表的是命令。第一個數(shù)組值是gawk命令后的第一個命令行參數(shù)。

當(dāng)要在 gawk 程序中跟蹤數(shù)據(jù)字段和記錄時,變量FNR 、 NF 和 NR 用起來就非常方便。有時并不知道記錄中到底有多少個數(shù)據(jù)字段。NF 變量可以讓你在不知道具體位置的情況下指定記錄中的最后一個數(shù)據(jù)字段。


操作示例:



一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_shell_17

NF 變量含有數(shù)據(jù)文件中最后一個數(shù)據(jù)字段的數(shù)字值??梢栽谒懊婕觽€美元符將其用作字段


變量。



FNR 和 NR 變量雖然類似,但又略有不同。 FNR 變量含有當(dāng)前數(shù)據(jù)文件中已處理過的記錄數(shù),


NR 變量則含有已處理過的記錄總數(shù)。下面的例子我們可以看到差別:


演示截圖:



一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_基礎(chǔ)運(yùn)維_18


?命令解說:

本例中g(shù)awk 程序的命令行定義了兩個輸入文件(兩次指定的是同樣的輸入文件)。 這個腳本會打印第一個數(shù)據(jù)字段的值和FNR 變量的當(dāng)前值。注意,當(dāng) gawk 程序處理第二個數(shù)據(jù)文件時,F(xiàn)NR 值被設(shè)回了 1 。


演示截圖:?

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_基礎(chǔ)運(yùn)維_19

?命令解說:

FNR 變量的值在 gawk 處理第二個數(shù)據(jù)文件時被重置了,而 NR 變量則在處理第二個數(shù)據(jù)文件時 繼續(xù)計數(shù)。結(jié)果就是:如果只使用一個數(shù)據(jù)文件作為輸入,F(xiàn)NR 和 NR 的值是相同的;如果使用多 個數(shù)據(jù)文件作為輸入,F(xiàn)NR 的值會在處理每個數(shù)據(jù)文件時被重置,而 NR 的值則會繼續(xù)計數(shù)直到處 理完所有的數(shù)據(jù)文件。

2.2 自定義變量

gawk 允許定義自己的變量在程序代碼中使用。 gawk 自定義變量名可以是任意數(shù)目的字母、數(shù)字和下劃線,但不能以數(shù)字開頭。重要的是,要記住gawk 變量名區(qū)分大小寫。

2.2.1 在腳本中給變量賦值

示例截圖:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_awk_20

命令說明:

此示例中,a保存了前面賦予的值。

?截圖示例:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_linux_21

?命令說明:

賦值語句還可以包含數(shù)學(xué)算式來處理數(shù)字值。

2.2.2. 在命令行上給變量賦值

gawk可以在 命令行來給程序中的變量賦值。允許在正常的代碼之外賦值,即時改變 變量的值。

演示截圖:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_基礎(chǔ)運(yùn)維_22

?說明:

使用命令行參數(shù)來定義變量值會有一個問題。在你設(shè)置了變量后,這個值在代碼的 BEGIN 部

分不可用。此時需要用到 -v參數(shù)來解決這個問題。

操作示例:

一篇速學(xué)企業(yè)linux awk命令詳解與應(yīng)用(上篇)_linux_23


?

本文摘自 :https://blog.51cto.com/u

開通會員,享受整站包年服務(wù)立即開通 >