第1章 三劍客基礎入門
要弄懂awk程序,必須熟悉瞭解這個工具的規則。本實戰筆記的目的是通過實際案例或面試題帶同學們熟練掌握awk在企業中的用法,而不是awk程序的幫助手冊
1.1 awk簡介
一種名字怪異的語言
模式掃描和處理
awk不僅僅時linux系統中的一個命令,而且是一種編程語言,可以用來處理數據和生成報告(excel)。處理的數據可以是一個或多個文件,可以是來自標準輸入,也可以通過管道獲取標準輸入,awk可以在命令行上直接編輯命令進行操作,也可以編寫成awk程序來進行更爲複雜的運用。本章主要講解awk命令的運用。
1.1 學完awk你可以掌握
記錄與字段
模式匹配:模式與動作
基本的awk執行過程
awk常用的內置變量(預定義變量)
awk語法:循環,條件
awk常用函數
向awk傳遞參數
awk引用shell變量
awk小程序及調試思路
1.2 awk的格式
awk指定是由模式,動作,或者模式和動作的組合組成
模式pattern,可以類似理解成sed模式匹配,可以有表達式組成,也可以是兩個正斜槓 / /直接的正則表達式。比如NR==1,這就是模式,可以把它理解爲一個條件。
動作action,是由大括號裏面的一條或多條語句組成,語句直接使用分號隔開。比如awk使用格式:
awk處理的內容可以來自標準輸入< ,一個或多個文本文件或管道。
patter既模式,也可以理解成爲條件,也叫找誰,你找誰?高矮,胖瘦,男女?都是條件,既模式。
action既動作,可以理解成幹啥,找到人之後要做什麼。
模式和動作的詳細介紹我們放在後面部分,現在大家要對awk結構有一個瞭解。
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指定流程圖
1.8 小結awk執行過程
awk讀入第一行內容
判斷是否符合模式中的條件NR>=2
a) 如果匹配則執行相應的動作{print $0}
b)如果不匹配條件,繼續讀取下一行
繼續讀取下一行
重複過程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
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 ☆字段(列)
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
1.23 字段與記錄小結()
現在你應該會對awk的記錄字段有所瞭解了,下面我們總結一下,學會給階段性知識總結是學好運維的必備技能。
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功能很強大,玩會了很牛逼。