三劍客老大之awk命令上篇

第1章 三劍客基礎入門

  要弄懂awk程序,必須熟悉瞭解這個工具的規則。本實戰筆記的目的是通過實際案例或面試題帶同學們熟練掌握awk在企業中的用法,而不是awk程序的幫助手冊

1.1 awk簡介

  一種名字怪異的語言

  模式掃描和處理

awk不僅僅時linux系統中的一個命令,而且是一種編程語言,可以用來處理數據和生成報告(excel)。處理的數據可以是一個或多個文件,可以是來自標準輸入,也可以通過管道獲取標準輸入,awk可以在命令行上直接編輯命令進行操作,也可以編寫成awk程序來進行更爲複雜的運用。本章主要講解awk命令的運用。

1.1 學完awk你可以掌握

  1. 記錄與字段

  2. 模式匹配:模式與動作

  3. 基本的awk執行過程

  4. awk常用的內置變量(預定義變量)

  5. awk語法:循環,條件

  6. awk常用函數

  7. 向awk傳遞參數

  8. awk引用shell變量

  9. awk小程序及調試思路

 

1.2 awk的格式

  • awk指定是由模式,動作,或者模式和動作的組合組成

  • 模式pattern,可以類似理解成sed模式匹配,可以有表達式組成,也可以是兩個正斜槓 / /直接的正則表達式。比如NR==1,這就是模式,可以把它理解爲一個條件。

  • 動作action,是由大括號裏面的一條或多條語句組成,語句直接使用分號隔開。比如awk使用格式:

wKiom1j65j-DRSf3AACcOCC0VKQ197.png-wh_50

 

  • awk處理的內容可以來自標準輸入< ,一個或多個文本文件或管道。



  • patter既模式,也可以理解成爲條件,也叫找誰,你找誰?高矮,胖瘦,男女?都是條件,既模式。

  • action既動作,可以理解成幹啥,找到人之後要做什麼。

  • 模式和動作的詳細介紹我們放在後面部分,現在大家要對awk結構有一個瞭解。

  •  

 wKioL1j65n2gcZ2zAACoxSYWJp8316.png-wh_50

1.3 模式動作實戰一

 

實例1-1         

將/etc/passwd 第2行到第6行 及行號打印出來?

[root@admin /]# awk -F : 'NR==2,NR==6{printNR,$1}' /etc/passwd

2 bin

3 daemon

4 adm

5 lp

6 sync

 

[root@admin /]# cat /etc/passwd | awk -F :'NR>=2&&NR<=6{print NR,$1}' 

2 bin

3 daemon

4 adm

5 lp

6 sync

 

命令說明:

-F 指定分隔符爲冒號:相當於以“:” 爲菜刀,進行字段(列)切割

NR==2行, 到 NR==6 這部分是表示模式,是一個條件,表示取第二行到第六行

NR>=2 && NR<=6   條件大於等於2行 並且 小於等於6行 

{pirnt NR,$1}    這部分表示動作,要幹什麼,表示要輸出NR行號和$1第一列

 

1.3.2 只有模式(條件)

[root@admin /]# awk -F : 'NR>=2 &&NR<=6' /etc/passwd

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologi006E  

sync:x:5:0:sync:/sbin:/bin/sync

 

命令說明:

-F 指定分隔符爲冒號:

NR>=2 && NR<=6 這部分是條件,表示取第2行到第6行

注意:但是這裏沒有動作,這裏大家需要了解如果只有條件(模式)沒有動作,awk默認輸出整行。

 

1.3.3 只有動作(幹什麼)

[root@admin /]# awk -F : '{print NR,$1}'/etc/passwd

1 root

2 bin

3 daemon

4 adm

5 lp

6 syn

….以下省略

 

命令說明:

-F 指定分隔符爲冒號:

這裏沒有條件,表示對每一行都處理

{print NR,$1} 表示動作,顯示NR行號與$1第一列內容

這裏要理解沒有條件的時候,awk會處理每一行

 

1.3.4 多個模式和動作

[root@admin /]# awk -F : 'NR==1{printNR,$1}NR==2{print NR,$NF}' /etc/passwd

1 root

2 /sbin/nologin

 

命令說明:

-F 指定分隔符爲冒號:

這裏有多個條件與動作的組合

NR==1 表示條件,行號NR 等於1條件滿足的時候,執行{print NR,$1} 動作,輸入行號與第一列

NR==2表示條件,行號(NR)等於2的條件滿足的時候,執行{print NR,$NF}動作,輸出行號與最後一列($NF)

1.4 注意:

  • pattern和{action} 需要用單引號引起來,防止shell作解釋

awk -F : 'NR==1{print NR,$1}NR==2{print NR,$NF}'/etc/passwd

  • Pattern模式是可選的。如果不指定,awk將處理輸入文件中的所有記錄。如果指定一個模式,awk則只處理匹配指定的模式的記錄。

  • {action}動作爲awk命令,可以是單個命令,也可以是多個命令。整個action(包括裏面的所有命令)都必須放在{和}之間。

  • action必須被{action} 包裹,沒有被{action}包裹就是patern.

  • file要處理的目標文件。

  • 執行過程

  • 前,我們需要知道awk如何處理文件的。

在深入瞭解awk前,我們需要知道awk如何處理文件的。

實例1-2        示例文件的創建

[root@admin ~]# mkdir /server/files/ -p

[root@admin ~]# head /etc/passwd >/server/files/awkfile.txt

[root@admin ~]# cat /server/files/awkfile.txt

root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

sync:x:5:0:sync:/sbin:/bin/sync

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

halt:x:7:0:halt:/sbin:/sbin/halt

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

  這個文件僅包含十行文件,我們使用下面的命令:

實例1-3        示例1-6 awk執行過程演示

[root@admin ~]# awk 'NR>=2{print $0}'/server/files/awkfile.txt

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

sync:x:5:0:sync:/sbin:/bin/sync

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

halt:x:7:0:halt:/sbin:/sbin/halt

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

 

命令說明:

條件NR>=2,表示行號大於等於2時候,執行{print $0}顯示整行。

awk是通過一行一行的處理文件,這條命令中包含模式部分(條件)和動作部分(動作),awk將處理模式(條件)指定的行

1.7 awk指定流程圖

 wKiom1j66WHCv1W9AAFCJpLrDC8972.png-wh_50

1.8 小結awk執行過程

  1. awk讀入第一行內容

  2. 判斷是否符合模式中的條件NR>=2

  3. a)     如果匹配則執行相應的動作{print $0}

  4. b)如果不匹配條件,繼續讀取下一行

  5. 繼續讀取下一行

  6. 重複過程1-3,直到讀取到最後一行(EFO;endof file 結束)

 

1.9 記錄和字段

接下來我給大家來帶兩個新概念記錄和字段,這裏爲了方便大家理解可以把記錄就當做行及記錄==行,字段相當於列。

名稱

含義

record

記錄,行

field

字段,列

 

1.10 記錄(行)

awk對每個要處理的輸入數據認爲都是具有格式和結構的,而不僅僅是一堆字符串。默認情況下,每一行內容都是一條記錄,並以換行符分隔(\n)結束。

實例1-4        查看一下下面這段文字

  1.思考:
一共有多少行呢?你如何知道的?通過什麼標誌?

root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

sync:x:5:0:sync:/sbin:/bin/sync

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

halt:x:7:0:halt:/sbin:/sbin/halt

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

 

1.11 ☆記錄分隔符-RS

wKiom1j66ajBOrhVAAHzF33tQC0279.png-wh_50

 

  • awk默認情況下每一行都是一個記錄(record)

  • RS及record separator 輸入輸出數據記錄分隔符,每一行是怎麼沒得,表示每個記錄輸入的時候的分隔符,既行與行之間如果分隔. \n

  • NR既number of record 記錄(行號),表示當前正在處理的記錄(行)的號碼

  • ORS既output record separator 輸出記錄分隔符

awk使用內置變量RS來存放輸入記錄分隔符,RS表示是輸入記錄分隔符,這個值可以通過BEGIN模塊重新定義修改。

1.12 使用“/”爲默認記錄分隔符 修改RS變量(默認是\n回車)特殊條件BEGIN

實例1-5         

[root@admin files]# cat awkfile.txt

root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

sync:x:5:0:sync:/sbin:/bin/sync

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

halt:x:7:0:halt:/sbin:/sbin/halt

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

 

 

#與上面對比發現我們現在是以 /進行換行

[root@admin files]# awk 'BEGIN{RS="/"}{print NR,$0}'awkfile.txt

1 root:x:0:0:root:

2 root:

3 bin

4 bash

bin:x:1:1:bin:     

 

root:x:0:0:root:/root:/bin/bash 

bin:x:1:1:bin:/bin:/sbin/nologin

看到這個應該明白是怎麼回事了吧對比

5 bin:

6 sbin

7 nologin

daemon:x:2:2:daemon:

8 sbin:

9 sbin

10 nologin

adm:x:3:4:adm:

11 var

12 adm:

13 sbin

14 nologin

lp:x:4:7:lp:

15 var

16 spool

17 lpd:

18 sbin

19 nologin

sync:x:5:0:sync:

20 sbin:

21 bin

22 sync

shutdown:x:6:0:shutdown:

23 sbin:

24 sbin

25 shutdown

halt:x:7:0:halt:

26 sbin:

27 sbin

28 halt

mail:x:8:12:mail:

29 var

30 spool

31 mail:

32 sbin

33 nologin

uucp:x:10:14:uucp:

34 var

35 spool

36 uucp:

37 sbin

38 nologin

 

命令說明

在每行開始先打印輸出NR(記錄號行號),並打印出每一行$0(整行)的內容

我們設置RS(記錄分隔符)的值“/” 表示一行(記錄)以“/” 結束

在awk眼中,文件是從頭到尾一段連續的字符串,恰巧中間有些\n(回車換行符),\n也是字符

 

1.13 ☆回顧記錄(行)到底是什麼意思?

  • 記錄(行):默認以\n(回車換行)結束。而這個行的結束不就是記錄分割符RS。

  • 所以在awk中,RS(記錄分隔符)變量表示這行的結束符號(默認是回車換行)

  • 在工作中,我們可以通過修改RS變量的值來決定行的結束標誌,最終來決定“每行”的內容

注意:

awk 的BEGIN模塊,在後面詳解,此處大家知道BEGIN模塊裏面定義一些awk內置變量即可。

1.14 對$0的認識

  $0表示整行,其實awk使用$0表示整條記錄。記錄分隔符存在RS變量中,或者說每個記錄以RS內置變量結束。

  另外,awk每一行的記錄都有一個內置變量NR來保存,沒處理完一條記錄,NR的值就會自動+1

  下面通過實例加深印象

[root@admin files]# awk '{print NR,$0}'awkfile.txt

1 root:x:0:0:root:/root:/bin/bash

2 bin:x:1:1:bin:/bin:/sbin/nologin

3 daemon:x:2:2:daemon:/sbin:/sbin/nologin

4 adm:x:3:4:adm:/var/adm:/sbin/nologin

5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

6 sync:x:5:0:sync:/sbin:/bin/sync

7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

8 halt:x:7:0:halt:/sbin:/sbin/halt

9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

 

命令說明:

NR及number of record ,當前記錄的記錄號,剛開始學也可以理解爲行號。

$0表示整行或者說整個記錄

1.15 企業面試題一:

1.15.1 企業面試題:按單詞出現頻率降序排序(計算文件中每個單詞的重複數量)

注:(此處使用sort與uniq即可)  

命令: sort 排序   uniq 配合sort 將重複的單詞等數字的合併

題目:

題目創建方法:
sed -r '1,10s#[^a-zA-Z]+# #g' /etc/passwd>/server/files/count.txt

 

[root@admin files]# cat count.txt

root x root root bin bash

bin x bin bin sbin nologin

daemon x daemon sbin sbin nologin

adm x adm var adm sbin nologin

lp x lp var spool lpd sbin nologin

sync x sync sbin bin sync

shutdown x shutdown sbin sbin shutdown

halt x halt sbin sbin halt

mail x mail var spool mail sbin nologin

uucp x uucp var spool uucp sbin nologin

~                                       

思路:

讓所有單詞排成一列,這樣每個單詞都是單獨的一行

  • 設置RS值爲空格
    2)將文件裏面的所有空格替換爲回車換行符“\n”
    3)grep所有連續的字母,grep-o參數讓他們排成一列。

方法:將所有字母排成一列

方法一:xargs 分組 將所有字母

[root@admin files]# xargs -n 1 < count.txt

 

方法二:修改默認的RS記錄分隔符 \n  換成空格  這樣就會顯示一列

[root@admin files]# awk 'BEGIN{RS=""}{print $0}' count.txt

 

方法三:tr雖然是sed的閹割版但是其功能還是挺強大的 所有的空格替換成\n換行符 這樣就達到我們想要的效果了  sed是一行一行讀入  放在模式空間換不了\n   

[root@admin files]# cat count.txt | tr "" "\n"

 

方法四: egrep將所有字母過濾出來

-o 精確匹配

利用正則表達式 小寫a到大寫Z

+ 連續重複前面一個字符或多個字符

# cat count.txt | egrep -o "[a-Z]+"

 

 

1.15.2 實戰解題

1.15.2.1         方法一:

[root@admin files]# xargs -n 1 < count.txt |sort | uniq -c

      3 adm

      1 bash

      5 bin

      2daemon

      3 halt

      2 lp

      1 lpd

      3 mail

      6nologin

      3 root

     12 sbin

      3shutdown

      3spool

      3 sync

      3 uucp

      4 var

     10 x

 

 

1.15.2.2         方法二:

[root@admin files]# awk 'BEGIN{RS=""}{print $0}' count.txt | sort | uniq -c

      1

      3 adm

      1 bash

      5 bin

      2daemon

      3 halt

      2 lp

      1 lpd

      3 mail

      6nologin

      3 root

     12 sbin

      3shutdown

      3spool

      3 sync

      3 uucp

      4 var

     10 x

1.15.2.3         方法三:

[root@admin files]# cat count.txt  | tr " " "\n" | sort  | uniq -c

      3 adm

      1 bash

      5 bin

      2daemon

      3 halt

      2 lp

      1 lpd

      3 mail

      6nologin

      3 root

     12 sbin

      3shutdown

      3spool

      3 sync

      3 uucp

      4 var

     10 x

 

 

1.15.2.4         方法四:

[root@admin files]# cat count.txt | egrep -o"[a-Z]+" | sort | uniq -c

      3 adm

      1 bash

      5 bin

      2daemon

      3 halt

      2 lp

      1 lpd

      3 mail

      6nologin

      3 root

     12 sbin

      3shutdown

      3spool

      3 sync

      3 uucp

      4 var

     10 x

 

1.16   awk記錄知識小結

  • NR存放着每個記錄的號(行號)讀取新行的時候會自動+1

  • RS是輸入數據的記錄的分隔符,簡單理解就是制定每個記錄的行的結尾標誌\n.

  • RS作用就是表示一個記錄的結束

  • ORS輸出數據的記錄的分隔符

  • 學習技巧一則:

大象放冰箱分幾步?打開冰箱,把大象放進去,關閉冰箱門。
awk也是一樣的,一步一步來,先修改了RS,然後用NR調試,看看到底如何分隔的。然後通過sort排序,uniq -c去重

1.18 ☆字段(列)

  • 每條記錄都是有多個區域(field)組成的,默認情況下區域之間的分隔符是由(及空格或製表符)來分隔,並且將分隔記錄在內置變量FS中,每行記錄的區域數

  • wKioL1j68ZDAR3qWAAJ4PkWHn-w486.png-wh_50


FS既fieldseparator,輸入字段(列)分隔符。分隔符就是菜刀,把一行字符串切爲很多個區域。

NF既number offileds,表示一行中(字段)的個數,可以理解爲菜刀且過一行後,切成了多少份。

1.19 OFS輸出字段(列)分隔符

  • awk使用內置變量FS來記錄區域分隔符的內容,FS可以在命令行上通過-F 參數來更改,也可以通過BEGIN模塊來更改。'BEGIN{FS=":"}{printNR,$1}'

 

  • 然後通過$n,n是整數,來取被切割後的區域,$1取第一個區域,    $2取第二個區域,$NF取最後一個區域。

  • 下面通過實例來加強學習:

實例1-6        指定分割符:

[root@admin files]# awk -F " " '{print$1}' count.txt

root

bin

daemon

adm

 

命令說明:

以:(冒號) 爲分隔符,打印第一列內容

  • 此處的FS是一個字符,其實他可以指定多個字符,此時FS指定的值可以是一個正則表達式。

  • 正常情況下,當你指定分隔符(非空格)的時候,例如指定多個區域分隔符,每個分隔符就是一把刀,把左右兩邊切爲兩個部分。

實例1-7        同時取出zhaokai和10206334這兩個內容。

[root@admin files]# cat qq.txt

I am zhaokai,my qq is 10206334

思路:

我們用默認的想法一次使用一把刀,需要配合管道的。如果同時使用兩把刀呢?看下面的結果

[root@admin files]# awk -F "[ ,]"'{print $3,$NF}' qq.txt

zhaokai 10206334

 

命令說明:

通過命令-F 參數指定區域分隔符

[, ] 是正則表達式裏面的內容,它表示一個整體,一個空格和一個逗號,合併在一起,就表示以空格或者逗號爲區域分隔符。

 

小技巧:

  在動作(‘{print \$3,\$NF}’)裏面的逗號,表示空格,其實動作中的逗號就是OFS的值,我們會在後面說明。剛開始大家把動作中的都逗號,當作空格即可。

1.21 默認分隔符和指定分隔符會有些差異

 

例:默認分隔符和指定分隔符會有些差異

[root@admin files]# ifconfig eth0 | awk 'NR==2'>/server/files/awkblank.txt

[root@admin files]# cat /server/files/awkblank.txt

         inet addr:192.168.197.133 Bcast:192.168.197.255 Mask:255.255.255.0

#默認分隔符時候

[root@admin files]# awk '{print $1}'/server/files/awkblank.txt

inet

#指定分隔符時候

[root@admin files]# awk -F "[ :]+"'{print $1}' /server/files/awkblank.txt

 

[root@admin files]# awk -F "[ :]+"'{print $2}' /server/files/awkblank.txt

inet

 

命令說明:

awk默認的FS分隔符對於空格序列,一個空格或多個空格tab都認爲是一樣的,一個整體。

  • 這個文件的開頭有很多連續的空格,然後纔是inet這個字符

  • 當我們使用默認的分隔符的時候,$1是有內容的。

  • 當我們指定其他分隔符(非空格)時候,區域會有所變化

  • 到底爲何會這樣,我們在這裏不再深入研究,只要瞭解有這種情況,注意一下即可。

 

1.22 ORS與OFS簡介修改FS、RS

現在說說ORS和OFS這兩個內置變量的含義。

  RS是輸入記錄分隔符,決定awk如何讀取或分隔每行(記錄)

  ORS表示輸出記錄分隔符,決定awk如何輸出一行(記錄)的,默認是回車換行(\n)

  FS是輸入區域分隔符,決定awk讀入一行後如何再分爲多個區域。

  OFS表示輸出區域分隔符,決定awk輸出每個區域的時候使用什麼分隔她們。

  awk無比強大,你可以通過RS,FS決定awk如何讀取數據。你也可以通過修改ORS,OFS的值指定awk如何輸出數據。

修改FS

[root@admin /]# awk 'BEGIN{FS=":"}{print$1}' /etc/passwd

 

修改RS   記得查看是用NR顯示行號比較方便

[root@admin /]# awk 'BEGIN{RS=":"}{print$0}' /etc/passwd

 

wKiom1j68dfCxlgcAAHzef-nJMc351.png-wh_50

1.23 字段與記錄小結()

  現在你應該會對awk的記錄字段有所瞭解了,下面我們總結一下,學會給階段性知識總結是學好運維的必備技能。

wKiom1j68gvx0wsRAAJ3_ebTPnU933.png-wh_50

RS記錄分隔符,表示每行的結束標誌,默認是\n

NR行號(記錄號)

FS字段分隔符,每列的分隔標誌或結束標誌

NF就是每行有多少列,每個記錄中字段的數量

$符號就是取某個列(字段),$1$2$NF

FS ( awk -F )分隔符,-F “:”《==》‘BEGIN{FS=":"}’

RS記錄分隔符(行的結束標示)

選擇合適的刀FS,RS,OFS,ORS

分隔符è結束標示

記錄與區域字段,你就對我們所謂的行與列,有了新的認識。

1.24 awk基礎入門總結

  • awk命令行結構

  • awk的模式和動作

  • awk的記錄和字段

  • 比較核心常用的是字段

  • 另外這些企業面試題可是學會awk的必備,必須自己能寫出來。

第2章 awk進階

2.1 awk模式與動作

接下來就詳細介紹下,awk的模式都有幾種

  • 正則表達式作爲模式

  • 比較表達式作爲模式

  • 範圍模式

  • 特殊模式BEGIN和END

awk的模式是你玩好awk必備也是最基礎的內容,必須熟練掌握

2.2 正則表達式作爲模式

  awk同sed一樣也可以通過模式匹配來對輸入的文本進行匹配。說到模式匹配,肯定少不了正則表達式模式,大部分與sed支持的元字符類似,而且正則表達式是玩轉三劍客必備工具,下表列出awk支持的正則表達式元字符:

 

awk模式就支持正則表達式符號

元字符

功能

示例

解釋

^

字符串開頭

/^admin/或\$3~/^admin/

匹配所有以admin開頭的字符串;匹配出所有第三列中以admin開頭的

\$

字符串結尾

/admin$/或$3~/admin$/

匹配所有以admin結尾的字符串;匹配第三列中以admin結尾的

.(點)

匹配任意但個字符(包括回車符)

/c..l/

匹配字母c,然後兩個任意字符,再以l結尾的行

*

重複0個或多個前一個字符

/a*cool/

匹配0個或多個a之後緊跟着cool的行

+

重複前一個字符一次或多次

/a+b/

匹配一個或多個a加上字符串b的行

?

匹配0個或一個前邊的字符

/a?b/

匹配以字母a或b或c開頭的行

[]

匹配指定字符組內的任一個字符

/^[abc]/

匹配以字母a或b或c開頭的行

[^]

匹配不在指定字符組內的任一字符

/^[^abc]/

匹配不以字母a或b或c開頭的行

()

子表達式組合

/(admin)+/

表示一個或多個cool組合,當有一些字符需要組合時,使用括號括起來

|

或者的意思

/(admin)|B/

匹配admin或字母B的行

 

 

2.3 ☆awk正則匹配操作符

 

awk正則匹配的操作符

~

 

 

用於對記錄或區域的(行列)表達式進行匹配

awk '$1/zhaokai/{print $1}' test.txt

 

用於表達式與~相反的意思

 

 

實戰例子:

root@admin files]# cat zhaokai.txt | awk'$1~/zhaokai/'

zhaokai like linux

[root@admin files]# cat zhaokai.txt | awk'$1~/zhaokai/{print $1}'

zhaokai

 

2.4 下面通過具體例子看看,awk如果通過正則表達式字符串的

2.4.1 awk正則表達式匹配整行

[root@admin files]# awk '/^root/{print $1}'awkfile.txt

root:x:0:0:root:/root:/bin/bash

 

和上面效果一樣

[root@admin files]# awk -F ":"'$0~/^root/' awkfile.txt

root:x:0:0:root:/root:/bin/bash

awk只用正則表達式的時候是默認匹配整行的即‘$0~/^root/’和‘/^root/’是一樣的。

 

打印最後一列 -F 指定分隔符 :

[root@admin files]# awk -F ":"'/^root/{print $NF}' awkfile.txt

/bin/bash

 

2.4.2 awk正則表達式匹配一行中的某一列

[root@admin files]# awk -F ":"'$5~/shutdown/' awkfile.txt

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

 

  • 提示:

  • $5表示第五個區域(列)

  • ~表示匹配(正則表達式匹配)

  • /shutdown/表示匹配shutdown這個字符串

  • 合併在一起

  • $5~/shutdown/表示第五個區域(列)匹配正則表達式/shutdown/,既第5列包含shutdown這個字符串,則顯示這一行。

 

 

2.5某個區域中的開頭和結尾

  • ^匹配一個字符串的開頭|
    $匹配一個字符串的結尾|

  • 在sed和grep這兩個命令中,我們都把它們當作行的開頭和結尾。但是在awk中它表示的是字符串的開頭和結尾

 

2.6接下來我們通過練習題來聯繫awk如何使用正則表達式。

2.6.1 創建測試環境

[root@admin files]# vim reg.txt

Zhang Dandan   41117397   :250:100:175

Zhang Xiaoyu   390320151  :155:90:201

Meng Feixue    80042789   :250:60:50

Wu   Waiwai    70271111  :250:80:75

Liu  Bingbing  41117483   :250:100:175

Wang Xiaoai    3515064655 :50:95:135

Zi   Gege      1986787350 :250:168:200

Li   Youjiu    918391635  :175:75:300

Lao  Nanhai    918391635  :250:100:175

~                                            

 

2.6.2測試文件說明

  • 第一列是姓氏

  • 第二列是名字

  • 第一列第二列合起來就是姓名

  • 第三列是對應的ID號碼

  • 最後三列是三次捐款數量

  • awk正則表達式練習題

  • 練習題1:顯示姓Zhang的人的第二次捐款金額及她的名字

  • 練習題2:顯示Xiaoyu的名字和ID號碼

  • 練習題3:顯示所有以41開頭的ID號碼的人的全名和ID號碼

  • 練習題4:顯示所有以一個D或X開頭的人名全名

  • 練習題5:顯示所有ID號碼最後一位數字是1或5的人的全名

  • 練習題6:顯示Xiaoyu的捐款,每個值都有以$開頭。如$520$200$135

  • 練習題7:顯示所有人的全名,以姓,名的格式顯示,如Meng,Feixue

  • 1顯示姓Zhang的人的第二次捐款金額及她的名字

方法一:必須掌握

[root@admin files]# awk -F "[ :]+"'$1~/^Zhang/{print $1,$5}' reg.txt

Zhang 100

Zhang 90

 

方法二:

[root@admin files]awk -F "[ :]+"'$1~/^Zhang/{print $2,$(NF-1)}' reg.txt

 

 

/Zhang/ 條件  這一行中如果有Zhang滿足條件 

第一列 或者以Zhang 開頭並結尾

說明:

-F 指定分隔符,現在知道-F 及FS也是支持正則表達式的。

[: ]+  表示連續空格或冒號  +重複一個或一個以上前面的字符。

/Zhang/ 表示條件,整行中包含Dan字符的這個條件

{print $1,$5}表示動作,滿足條件後,執行顯示第一列和第五列

注意:
NF是一行中有多少列,NF-1整行就是倒數第二列。
$(NF-1)就是取倒數第二列內容。

2.6.52顯示Xiaoyu的名字和ID號碼

方法一:必須掌握

[root@admin files]# awk '$2~/Xiaoyu/{print $1,$3}'reg.txt

Zhang 390320151

 

方法二:

[root@admin files]# awk -F "[ :]+"'$2~/^Xiaoyu/{print $1,$3}' reg.txt

命令說明:

指定分隔符-F “【:】+”

$2~/Xiaoyu/表示條件,第二列包含Xiaoyu時候執行對應的動作

{print $1,$3}表示動作,顯示第一列和第三列的內容

 

思路:

[root@oldboyedu-35 files]# ###第一個里程碑-確定好目標並選好武器 
[root@oldboyedu-35 files]# ###第二里程碑-- 確定好條件    找誰
[root@oldboyedu-35 files]# awk '$2~/Xiaoyu/' reg.txt 
Zhang Xiaoyu    390320151  :155:90:201
[root@oldboyedu-35 files]# 
[root@oldboyedu-35 files]# ###第三個里程碑-只顯示你想要的內容

 

2.6.63顯示所有以41開頭的ID號碼的人的全名和ID號碼

方法以:

[root@admin files]# awk '$3~/^41/{print $1,$2,$3}'reg.txt

Zhang Dandan 41117397

Liu Bingbing 41117483

 

第一步:確定好目標

第二步:確定好條件 找誰

第三步:顯示你想要的內容

2.6.74顯示所有以一個D或X開頭的人名全名

方法一:

[root@admin files]# awk '$2~/^[DX]/{print $1,$2}'reg.txt

Zhang Dandan

Zhang Xiaoyu

Wang Xiaoai

 

方法二:

[root@admin files]awk -F "[ :]+"'$2~/^D|^X/{print $1,$2}' reg.txt

Zhang Dandan

Zhang Xiaoyu

Wang Xiaoai

 

命令說明:

^以什麼開頭

|  或

注意:
這裏要用[ ]括號表示即^[DX]相當於^D|^X,有的同學寫成^D|X這樣是錯誤的。

2.6.85顯示所有ID號碼最後一位數字是1或5的人的全名

#和第三題類型

方法一:

[root@admin files]# awk '$3~/[15]$/{print $1,$2}'reg.txt

Zhang Xiaoyu

Wu Waiwai

Wang Xiaoai

Li Youjiu

Lao Nanhai

 

方法二:

[root@admin files]awk -F "[ :]+"'$3~/1$|5$/{print $1,$2}' reg.txt

Zhang Xiaoyu

Wu Waiwai

Wang Xiaoai

Li Youjiu

Lao Nanhai

 

 

2.6.96: 顯示Xiaoyu的捐款,每個值都有以$開頭。如$520$200$135

方法一:

awk -F "[ :]+" '$2~/Xiaoyu/{print"$"$4"$"$5"$"$6}' reg.txt

 

方法二:awk替換強大功能

[root@admin files]# awk'/Xiaoyu/{gsub(/:/,"$");print $4}' reg.txt

$155$90$201

 

[root@oldboyedu-35 files]# ###awk內置的功能(函數)
[root@oldboyedu-35 files]# ####查找 替換    gsub 
[root@oldboyedu-35 files]# ####gsub(/找誰/,"替換成什麼")
[root@oldboyedu-35 files]# ####gsub(/找誰/,"替換成什麼",替換那個部分)

 

2.6.107:顯示所有人的全名,以姓,名的格式顯示,如Meng,Feixue

方法一:

[root@admin files]# awk '{print $1,$2}' reg.txt

Zhang Dandan

Zhang Xiaoyu

Meng Feixue

Wu Waiwai

Liu Bingbing

Wang Xiaoai

Zi Gege

Li Youjiu

Lao Nanhai

 

方法二:

[root@admin files]awk -F "[ ]+" '{print$1","$2}' reg.txt


awk功能很強大,玩會了很牛逼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章