awk--基本操作一

通過(guò)學(xué)習(xí)《awk精通》整理

作者: 駿馬金龍
學(xué)習(xí)鏈接: https://www.junmajinlong.com/how_to_nav_posts/
學(xué)習(xí)來(lái)源: 駿馬金龍
思維導(dǎo)圖查看

what

awk是一個(gè)文本處理工具

awk基本用法

鋪墊:文件讀取的幾種方式

1. 按字符數(shù)量讀取:每一次可以讀取一個(gè)字符,或者多個(gè)字符,直到把整個(gè)文件讀取完
         while read -n 1 char;do echo $char;done <a.txt
2. 按照分隔符進(jìn)行讀取:一直讀取直到遇到了分隔符才停止,下次繼續(xù)從分隔的位置處向后讀取,直到讀完整個(gè) 文件
while read -d "m" chars;do echo "$chars";done <a.txt 
# 以字符'm'為分割點(diǎn)
3. 按行讀取:每次讀取一行,直到把整個(gè)文件讀完
是按照分隔符讀取的一種特殊情況:將分隔符指定為了換行符 \n while read line;do echo "$line";done <a.txt
4. 一次性讀取整個(gè)文件 是按字符數(shù)量讀取的特殊情況,也是按分隔符讀取的特殊情況
read -N 10000000 data <a.txt
echo "$data #展示

read -d '_' data <a.txt
echo "$data" #展示

awk用法入門(mén)

 awk 'awk_program' a.txt
  • a.txt是awk要讀取的文件,可以是0個(gè)文件或一個(gè)文件,也可以多個(gè)文件
    • 如果不給定任何文件,但又需要讀取文件,則表示從標(biāo)準(zhǔn)輸入中讀取
  • 單引號(hào) 包圍的是awk代碼,也稱為awk程序
    • 盡量使用單引號(hào),因?yàn)樵赼wk中經(jīng)常使用 符號(hào),而符號(hào)在Shell是變量符號(hào),如果使用雙引號(hào)包圍 awk代碼,
      符號(hào)會(huì)被Shell解析成Shell變量,然后進(jìn)行Shell變量替換。使用單引號(hào)包圍awk代碼, 則 會(huì)脫離Shell的魔掌,使得$符號(hào)留給了awk去解析
  • awk程序中,大量使用大括號(hào),大括號(hào)表示代碼塊,代碼塊中間可以之間連用,代碼塊內(nèi)部的多個(gè)語(yǔ)句需使用分 號(hào)";"分隔
awk '{print $0}' a.txt
awk '{print $0}{print $0;print $0}' a.txt

BEGIN和END語(yǔ)句塊

awk 'BEGIN{print "我在前面"}{print $0}' a.txt
awk 'END{print "我在后面"}{print $0}' a.txt
awk 'BEGIN{print "我在前面"}{print $0}END{print "我在后面"}' a.txt

BEGIN代碼塊:

  • 在讀取文件之前執(zhí)行,且執(zhí)行一次
  • 在BEGIN代碼塊中,無(wú)法使用 $0 或其它一些特殊變量

END代碼塊:

  • 在讀取文件完成之后執(zhí)行,且執(zhí)行一次
  • 有END代碼塊,必有要讀取的數(shù)據(jù)(可以是標(biāo)準(zhǔn)輸入)
  • END代碼塊中可以使用$0等一些特殊變量,只不過(guò)這些特殊變量保存的是最后一輪awk循環(huán)的數(shù)據(jù)

main代碼塊:

  • 讀取文件時(shí)循環(huán)執(zhí)行,(默認(rèn)情況)每讀取一行,就執(zhí)行一次main代碼塊
  • main代碼塊可有多個(gè)

安裝新版本gawk

# 1.下載
wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/gnu/gawk/gawk-4.2.0.tar.gz
# 2.解壓、進(jìn)入解壓后目錄
tar xf gawk-4.2.0.tar.gz
cd gawk-4.2.0/
# 3.編譯
./configure --prefix=/usr/local/gawk4.2 && make && make install
# 4.創(chuàng)建一個(gè)軟鏈接:讓awk指向剛新裝的gawk版本
ln -fs /usr/local/gawk4.2/bin/gawk /usr/bin/awk
# 此時(shí),調(diào)用awk將調(diào)用新版本的gawk,調(diào)用gawk將調(diào)用舊版本的gawk awk --version
gawk --version

系統(tǒng)深入awk

awk命令行結(jié)構(gòu)和語(yǔ)法結(jié)構(gòu)

在Shell命令行當(dāng)中,雙短橫線 -- 表示選項(xiàng)到此結(jié)束,后面的都是命令的參數(shù)。

awk [ -- ] program-text file ...
awk -f program-file [ -- ] file ...
awk -e program-text [ -- ] file ...

cmd -x -r root -ppassword a.txt b.txt c.txt
# 1.選項(xiàng)分為長(zhǎng)選項(xiàng)和短選項(xiàng) 
# 2.選項(xiàng)分為3種:
#       (1).不帶參數(shù)的選項(xiàng)
#       (2).是帶參數(shù)的選項(xiàng),如果該選項(xiàng)后面沒(méi)有給參數(shù),則報(bào)錯(cuò)
#       (3).參數(shù)可選的選項(xiàng),選項(xiàng)后面可以跟參數(shù),也可以不跟參數(shù)
#          參數(shù)可選選項(xiàng),如果要接參數(shù),則必須將參數(shù)緊緊跟在選項(xiàng)后面,不能使用空格分隔選項(xiàng)和參數(shù)
#3.兩種參數(shù):
#   (1).選項(xiàng)型參數(shù)
#   (2).非選項(xiàng)型參數(shù)

awk的語(yǔ)法充斥著 pattern{action} 的模式,它們稱為awk rule:

awk 'BEGIN{n=3} /^[0-9]/{$1>5}{$1=333;print $1} /Alice/{print "Alice"} END{print "hello"}' a.txt
  • pattern部分用于測(cè)試篩選數(shù)據(jù),action表示在測(cè)試通過(guò)后執(zhí)行的操作
    • 省略 pattern ,等價(jià)于對(duì)每一行數(shù)據(jù)都執(zhí)行action
      • awk '{print $0}' a.txt
    • 省略代碼塊{action} ,等價(jià)于 {print} 即輸出所有行
      • awk '/Alice/' a.txt 等價(jià)于awk '/Alice/{print $0}' a.txt
    • 省略代碼塊中的 ,表示對(duì)篩選的行什么都不做
      • awk '/Alice/{}' a.txt
    • pattern{action}任何一部分都可以省略
      + awk '' a.txt
    
  • 多個(gè) pattern{action} 可以直接連接連用

pattern和action

對(duì)于 pattern{action} 語(yǔ)句結(jié)構(gòu)(都稱之為語(yǔ)句塊),其中的pattern部分可以使用下面列出的模式:

# 特殊pattern BEGIN
END
# 布爾代碼塊
/regular expression/ # 正則匹配成功與否 /a.*ef/{action}
relational expression # 即等值比較、大小比較 3>2{action}
pattern && pattern   # 邏輯與 3>2 && 3>1 {action}

pattern || pattern # 邏輯或 3>2 || 3<1 {action}
! pattern # 邏輯取反 !/a.*ef/{action} 
(pattern) # 改變優(yōu)先級(jí)
pattern ? pattern : pattern # 三目運(yùn)算符決定的布爾值

# 范圍pattern,非布爾代碼塊
pattern1, pattern2 # 范圍,pat1打開(kāi)、pat2關(guān)閉,即flip,flop模式

action部分,可以是任何語(yǔ)句,例如print語(yǔ)句。

awk讀取文件

詳細(xì)分析awk如何讀取文件

awk讀取輸入文件時(shí),每次讀取一條記錄(record)(默認(rèn)情況下按行讀取,所以此時(shí)記錄就是行)。
每讀取一條記錄,將其保存到 $0中,然后執(zhí)行一次main代碼段。

awk '{print $0}' a.txt

如果是空文件,則因?yàn)闊o(wú)法讀取到任何一條記錄,將導(dǎo)致直接關(guān)閉文件,而不會(huì)進(jìn)入main代碼段。
但是BEGIN END會(huì)進(jìn)行執(zhí)行。

touch x.log # 創(chuàng)建一個(gè)空文件
awk '{print "hello world"}' x.log

可設(shè)置表示輸入記錄分隔符的預(yù)定義變量RS(Record Separator)來(lái)改變每次讀取的記錄模式。

# RS="\n" 、 RS="m"
awk 'BEGIN{RS="\n"}{print $0}' a.txt 
awk 'BEGIN{RS="m"}{print $0}' a.txt

RS通常設(shè)置在BEGIN代碼塊中,因?yàn)橐扔谧x取文件就確定好RS分隔符。

RS指定輸入記錄分隔符時(shí),所讀取的記錄中是不包含分隔符字符的。
例如 RS="a" ,則 $0 中一定不可能出現(xiàn) 字符a。

RS兩種可能情況:

  • RS為單個(gè)字符:直接使用該字符來(lái)分割記錄
  • RS為多個(gè)字符:將其當(dāng)做正則表達(dá)式,只要匹配正則表達(dá)式的符號(hào),都用來(lái)分割記錄
    • 設(shè)置預(yù)定義變量IGNORECASE為非零值,正則匹配時(shí)表示忽略大小寫(xiě)
    • 兼容模式下,只有首字符才生效,不會(huì)使用正則模式去分割記錄
      特殊的RS值用來(lái)解決特殊讀取需求:
    • 按段落讀取:RS=''
    • RS='\0' 一次性讀取所有數(shù)據(jù),但有些特殊文件中包含了空字符 \0
    • RS="^$" 真正的一次性讀取所有數(shù)據(jù),因?yàn)榉强瘴募豢赡芷ヅ涑晒?/li>
    • RS='\n+'按行讀取,但忽略所有空行
# 按段落讀取:RS=''
$ awk 'BEGIN{RS=''}{print $0"------"}' a.txt
# 一次性讀取所有數(shù)據(jù):RS='\0' RS="^$"
$ awk 'BEGIN{RS='\0'}{print $0"------"}' a.txt $ awk 'BEGIN{RS='^$'}{print $0"------"}' a.txt
# 忽略空行:RS='\n+'
$ awk 'BEGIN{RS='\n+'}{print $0"------"}' a.txt
# 忽略大小寫(xiě):預(yù)定義變量IGNORECASE設(shè)置為非0值
$ awk 'BEGIN{IGNORECASE=1}{print $0"------"}' RS='[ab]' a.txt
預(yù)定義變量RT:
在awk每次讀完一條記錄時(shí),會(huì)設(shè)置一個(gè)稱為RT的預(yù)定義變量,表示Record Termination。
當(dāng)RS為單個(gè)字符時(shí),RT的值和RS的值是相同的。
當(dāng)RS為多個(gè)字符(正則表達(dá)式)時(shí),則RT設(shè)置為正則匹配到記錄分隔符之后,真正用于劃分記錄時(shí)的字符。 
當(dāng)無(wú)法匹配到記錄分隔符時(shí),RT設(shè)置為控制空字符串(即默認(rèn)的初始值)。
awk 'BEGIN{RS="(fe)?male"}{print RT}' a.txt

兩種行號(hào):NR和FNR

在讀取每條記錄之后,將其賦值給$0,同時(shí)還會(huì)設(shè)置NR、FNR、RT。

  • NR:所有文件的行號(hào)計(jì)數(shù)器
  • FNR:是各個(gè)文件的行號(hào)計(jì)數(shù)器
awk '{print NR}' a.txt a.txt
awk '{print FNR}' a.txt a.txt

詳細(xì)的分段字段分割

awk讀取每一條記錄之后,會(huì)將其賦值給 0 ,同時(shí)還會(huì)對(duì)這條記錄按照預(yù)定義變量FS劃分字段,將劃分好的各個(gè)\ 字段分別賦值給1 23 4...N ,同時(shí)將劃分的字段數(shù)量賦值給預(yù)定義變量NF。

引用字段的方式

$N 引用字段:

  • N=0 :即 $0 ,引用記錄本身
  • 0<N<=NF :引用對(duì)應(yīng)字段
  • N>NF :表示引用不存在的字段,返回空字符串 N<0 :報(bào)錯(cuò)
    可使用變量或計(jì)算的方式指定要獲取的字段序號(hào)。
awk '{n = 5;print $n}' a.txt
awk '{print $(2+2)}' a.txt # 括號(hào)必不可少,用于改變優(yōu)先級(jí) 
awk '{print $(NF-3)}' a.txt

分割字段的方式

讀取record之后,將使用預(yù)定義變量FS、FIELDWIDTHS或FPAT中的一種來(lái)分割字段。分割完成之后,再進(jìn)入
main代碼段(所以,在main中設(shè)置FS對(duì)本次已經(jīng)讀取的record是沒(méi)有影響的,但會(huì)影響下次讀取)。

FS或-F

FS 或者 -F :字段分隔符

  • FS為單個(gè)字符時(shí),該字符即為字段分隔符
  • FS為多個(gè)字符時(shí),則采用正則表達(dá)式模式作為字段分隔符
  • 特殊的,也是FS默認(rèn)的情況,F(xiàn)S為單個(gè)空格時(shí),將以連續(xù)的空白(空格、制表符、換行符)作為字段分隔符
  • 特殊的,F(xiàn)S為空字符串""時(shí),將對(duì)每個(gè)字符都進(jìn)行分隔,即每個(gè)字符都作為一個(gè)字段
  • 設(shè)置預(yù)定義變量IGNORECASE為非零值,正則匹配時(shí)表示忽略大小寫(xiě)(只影響正則,所以FS為單字時(shí)無(wú)影響)
  • 如果record中無(wú)法找到FS指定的分隔符(例如將FS設(shè)置為"\n"),則整個(gè)記錄作為一個(gè)字段,即 1 和0 相 等

FIELDWIDTHS

指定預(yù)定義變量FIELDWIDTHS按字符寬度分割字段,這是gawk提供的高級(jí)功能。在處理某字段缺失時(shí)非常好用。
用法:

  • FIELDWIDTHS="3 5 6 9" 表示第一個(gè)字段3字符,第二字段5字符...
  • FIELDWIDTHS = "8 1:5 6 2:33"表示:
    • 第一個(gè)字段讀8個(gè)字符
    • 然后跳過(guò)1個(gè)字符再讀5個(gè)字符作為第二個(gè)字段
    • 然后讀6個(gè)字符作為第三個(gè)字段
    • 然后跳過(guò)2個(gè)字符在讀33個(gè)字符作為第四個(gè)字段(如果不足33個(gè)字符,則讀到結(jié)尾)
  • FIELDWIDTHS="2 3 *" :
    • 第一個(gè)字段2個(gè)字符
    • 第二個(gè)字段3個(gè)字符
    • 第三個(gè)字段剩余所有字符 星號(hào)只能放在最后,且只能單獨(dú)使用,表示剩余所有
  • 設(shè)置該變量后,F(xiàn)S失效
  • 之后再設(shè)置FS或FPAT,
    示例1:
# 沒(méi)取完的字符串DDD被丟棄,且NF=3
$ awk 'BEGIN{FIELDWIDTHS="2 3 2"}{print $1,$2,$3,$4}' <<<"AABBBCCDDDD" AA BBB CC
# 字符串不夠長(zhǎng)度時(shí)無(wú)視
$ awk 'BEGIN{FIELDWIDTHS="2 3 2 100"}{print $1,$2,$3,$4"-"}' <<<"AABBBCCDDDD" AA BBB CC DDDD-
# *號(hào)取剩余所有,NF=3
$ awk 'BEGIN{FIELDWIDTHS="2 3 *"}{print $1,$2,$3}' <<<"AABBBCCDDDD" AA BBB CCDDDD
# 字段數(shù)多了,則取完字符串即可,NF=2
$ awk 'BEGIN{FIELDWIDTHS="2 30 *"}{print $1,$2,NF}' <<<"AABBBCCDDDD" AA BBBCCDDDD 2

示例2:處理某些字段缺失的數(shù)據(jù)。
如果按照常規(guī)的FS進(jìn)行字段分割,則對(duì)于缺失字段的行和沒(méi)有缺失字段的行很難統(tǒng)一處理,但使用FIELDWIDTHS則非常方便。
假設(shè)a.txt文本內(nèi)容如下:

ID  name    gender  age  email          phone
1   Bob     male    28   abc@qq.com     18023394012
2   Alice   female  24   def@gmail.com  18084925203
3   Tony    male    21   aaa@163.com    17048792503
4   Kevin   male    21                  17023929033
5   Alex    male    18   ccc@xyz.com    18185904230
6   Andy    female  22   ddd@139.com    18923902352
7   Jerry   female  25   exdsa@189.com  18785234906
8   Peter   male    20   bax@qq.com     17729348758
9   Steven  female  23   bc@sohu.com    15947893212
10  Bruce   female  27   bcbd@139.com   13942943905

因?yàn)閑mail字段有的是空字段,所以直接用FS劃分字段不便處理??墒褂肍IELDWIDTHS。

# 字段1:4字符
# 字段2:8字符
# 字段3:8字符
# 字段4:2字符
# 字段5:先跳過(guò)3字符,再讀13字符,該字段13字符
# 字段6:先跳過(guò)2字符,再讀11字符,該字段11字符
awk '
BEGIN{FIELDWIDTHS="4 8 8 2 3:13 2:11"}
NR>1{
    print "<"$1">","<"$2">","<"$3">","<"$4">","<"$5">","<"$6">"
}' a.txt
# 如果email為空,則輸出它
awk '
BEGIN{FIELDWIDTHS="4 8 8 2 3:13 2:11"} NR>1{
    if($5 ~ /^ +$/){print $0}
}' a.txt

FPAT

FS是指定字段分隔符,來(lái)取得除分隔符外的部分作為字段。
FPAT是取得匹配的字符部分作為字段。它是gawk提供的一個(gè)高級(jí)功能。
FPAT根據(jù)指定的正則來(lái)全局匹配record,然后將所有匹配成功的部分組成 1、2... ,不會(huì)修改 $0 。

  • awk 'BEGIN{FPAT="[0-9]+"}{print $3"-"}' a.txt
  • 之后再設(shè)置FS或FPAT,該變量將失效
    FPAT常用于字段中包含了字段分隔符的場(chǎng)景。例如,CSV文件中的一行數(shù)據(jù)如下:
Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA

其中逗號(hào)分隔每個(gè)字段,但雙引號(hào)包圍的是一個(gè)字段整體,即使其中有逗號(hào)。
這時(shí)使用FPAT來(lái)劃分各字段比使用FS要方便的多。

echo 'Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA' |\
awk '
    BEGIN{FPAT="[^,]*|(\"[^\"]*\")"}
    {
        for (i=1;i<NF;i++){
            print "<"$i">"
        } 
    }
'

最后,patsplit()函數(shù)和FPAT的功能一樣。

檢查字段分隔的方式

有FS、FIELDWIDTHS、FPAT三種獲取字段的方式,可使用 PROCINFO 數(shù)組來(lái)確定本次使用何種方式獲得字段。
PROCINFO是一個(gè)數(shù)組,記錄了awk進(jìn)程工作時(shí)的狀態(tài)信息。

  • PROCINFO["FS"]=="FS",表示使用FS分割獲取字段
  • PROCINFO["FPAT"]=="FPAT" ,表示使用FPAT匹配獲取字段
  • PROCINFO["FIELDWIDTHS"]=="FIELDWIDTHS",表示使用FIELDWIDTHS分割獲取字段
    例如:
if(PROCINFO["FS"]=="FS"){
    ...FS spliting...
} else if(PROCINFO["FPAT"]=="FPAT"){
    ...FPAT spliting...
} else if(PROCINFO["FIELDWIDTHS"]=="FIELDWIDTHS"){
    ...FIELDWIDTHS spliting...
}

修改字段或NF值的聯(lián)動(dòng)效應(yīng)

注意下面的分割和計(jì)算兩詞:分割表示使用FS(field Separator),計(jì)算表示使用預(yù)定義變量OFS(Output Field Separator)。

  1. 修改 0 ,將使用 FS 重新分割字段,所以會(huì)影響1、$2...
  2. 修改 1、2 ,將根據(jù) 1 到NF 來(lái)重新計(jì)算 $0
    • 即使是 1 =1 這樣的原值不變的修改,也一樣會(huì)重新計(jì)算 $0
  3. 為不存在的字段賦值,將新增字段并按需使用空字符串填充中間的字段,并使用 OFS 重新計(jì)算 $0
    • awk '{(NF+2)=5;print0}' OFS='-' a.txt
  4. 增加NF值,將使用空字符串新增字段,并使用 OFS 重新計(jì)算 $0
    • awk '{NF+=3;print $0}' OFS='-' a.txt
  5. 減小NF值,將丟棄一定數(shù)量的尾部字段,并使用 OFS 重新計(jì)算 $0
    • awk '{NF-=3;print $0}' OFS='-' a.txt

關(guān)于$0

當(dāng)讀取一條record之后,將原原本本地被保存到 $0 當(dāng)中。

awk '{print $0}' a.txt

但是,只要出現(xiàn)了上面所說(shuō)的任何一種導(dǎo)致 0 重新計(jì)算的操作,都會(huì)立即使用OFS去重建0 。
換句話說(shuō),沒(méi)有導(dǎo)致 0 重建,0就一直是原原本本的數(shù)據(jù),所以指定OFS也無(wú)效。

awk '{print $0}' OFS="-" a.txt # OFS此處無(wú)效

當(dāng) $0 重建后,將自動(dòng)使用OFS重建,所以即使沒(méi)有指定OFS,它也會(huì)采用默認(rèn)值(空格)進(jìn)行重建。

awk '{$1=$1;print $0}' a.txt # 輸出時(shí)將以空格分隔各字段
awk '{print $0;$1=$1;print $0}' OFS="-" a.txt

如果重建 $0 之后,再去修改OFS,將對(duì)當(dāng)前行無(wú)效,但對(duì)之后的行有效。所以如果也要對(duì)當(dāng)前行生效,需要再次重 建。

# OFS對(duì)第一行無(wú)效
awk '{$4+=10;OFS="-";print $0}' a.txt
# 對(duì)所有行有效
awk '{$4+=10;OFS="-";$1=$1;print $0}' a.txt

關(guān)注 0 重建是一個(gè)非常有用的技巧。\ 例如,下面通過(guò)重建0 的技巧來(lái)實(shí)現(xiàn)去除行首行尾空格并壓縮中間空格

$ echo " a b c d " | awk '{$1=$1;print}'
a b c d
$ echo " a b c d " | awk '{$1=$1;print}' OFS="-" 
a-b-c-d

awk數(shù)據(jù)篩選示例

篩選行

# 1.根據(jù)行號(hào)篩選
awk 'NR==2' a.txt # 篩選出第二行
awk 'NR>=2' a.txt # 輸出第2行和之后的行

# 2.根據(jù)正則表達(dá)式篩選整行
awk '/qq.com/' a.txt # 輸出帶有qq.com的行 
awk '$0 ~ /qq.com/' a.txt # 等價(jià)于上面命令
awk '/^[^@]+$/' a.txt # 輸出不包含@符號(hào)的行 
awk '!/@/' a.txt # 輸出不包含@符號(hào)的行

# 3.根據(jù)字段來(lái)篩選行
awk '($4+0) > 24{print $0}' a.txt # 輸出第4字段大于24的行 
awk '$5 ~ /qq.com/' a.txt # 輸出第5字段包含qq.com的行

# 4.將多個(gè)篩選條件結(jié)合起來(lái)進(jìn)行篩選
awk 'NR>=2 && NR<=7' a.txt
awk '$3=="male" && $6 ~ /^170/' a.txt 
awk '$3=="male" || $6 ~ /^170/' a.txt

# 5.按照范圍進(jìn)行篩選 flip flop
# pattern1,pattern2{action}
awk 'NR==2,NR==7' a.txt # 輸出第2到第7行 
awk 'NR==2,$6 ~ /^170/' a.txt

處理字段

修改字段時(shí),一定要注意,可能帶來(lái)的聯(lián)動(dòng)效應(yīng):即使用OFS重建$0。

awk 'NR>1{$4=$4+5;print $0}' a.txt
awk 'NR>1{$6=$6"*";print $0}' a.txt

awk運(yùn)維面試試題

從ifconfig命令的結(jié)果中篩選出除了lo網(wǎng)卡外的所有IPv4地址。

# 1.法一:
ifconfig | awk '/inet / && !($2 ~ /^127/){print $2}'
# 2.法二:
ifconfig | awk 'BEGIN{RS=""}!/lo/{print $6}'
# 3.法三:
ifconfig | awk 'BEGIN{RS="";FS="\n"}!/lo/{$0=$2;FS=" ";$0=$0;print $2}'

awk工作流程

參考自: man awk 的"AWK PROGRAM EXECUTION"段。

man --pager='less -p ^"AWK PROGRAM EXECUTION" awk

執(zhí)行步驟

  1. 解析 -v var=val... 選項(xiàng)中的變量賦值
  2. 編譯awk源代碼為awk可解釋的內(nèi)部格式,包括-v的變量
  3. 執(zhí)行BEGIN代碼段
  4. 根據(jù)輸入記錄分隔符RS讀取文件(根據(jù)ARGV數(shù)組的元素決定要讀取的文件),如果沒(méi)有指定文件,則從標(biāo)準(zhǔn) 輸入中讀取文件,同時(shí)執(zhí)行main代碼段
    • 如果文件名部分指定為 var=val 格式,則聲明并創(chuàng)建變量,此階段的變量在BEGIN之后聲明,所以 BEGIN中不可用,main代碼段可用
    • 每讀取一條記錄:
      • 都將設(shè)置NR、FNR、RT、$0等變量
      • (默認(rèn))根據(jù)輸入字段分隔符FS切割字段,將各字段保存到 1、2... 中
      • 測(cè)試main代碼段的pattern部分,如果測(cè)試成功則執(zhí)行action部分
  5. 執(zhí)行END代碼段
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容