Shell編程、part5

本節(jié)內(nèi)容

1. 三劍客簡介

2. sed命令詳解

3. awk命令詳解

文本處理三劍客

在 Shell 下使用這些正則表達(dá)式處理文本最多的命令有下面幾個(gè)工具:

|                 命令 |                描述 |
| grep | 默認(rèn)不支持?jǐn)U展表達(dá)式,加-E 選項(xiàng)開啟 ERE。如果不加-E 使用花括號(hào)要加轉(zhuǎn)義符\{\} |
| egrep | 支持基礎(chǔ)和擴(kuò)展表達(dá)式 |
| awk | 支持 egrep 所有的正則表達(dá)式 |
| sed | 默認(rèn)不支持?jǐn)U展表達(dá)式,加-r 選項(xiàng)開啟 ERE。如果不加-r 使用花括號(hào)要加轉(zhuǎn)義符\{\} |

sed詳解

1. 前言

  • 我們都知道,在Linux中一切皆文件,比如配置文件,日志文件,啟動(dòng)文件等等。如果我們相對(duì)這些文件進(jìn)行一些編輯查詢等操作時(shí),我們可能會(huì)想到一些vi,vim,cat,more等命令。但是這些命令效率不高,而在linux中有三種工具:頂配awk,中配sed,標(biāo)配grep。使用這些工具,我們能夠在達(dá)到同樣效果的前提下節(jié)省大量的重復(fù)性工作,提高效率。

  • 文件內(nèi)容可以是來自文件,也可以直接來自鍵盤或者管道等標(biāo)準(zhǔn)輸入,最后的結(jié)果默認(rèn)情況下是顯示到終端的屏幕上,但是也可以輸出到文件中。

  • 編輯文件也是這樣,以前我們修改一個(gè)配置文件,需要移動(dòng)光標(biāo)到某一行,然后添加點(diǎn)文字,然后又移動(dòng)光標(biāo)到另一行,注釋點(diǎn)東西…….可能修改一個(gè)配置文件下來需要花費(fèi)數(shù)十分鐘,還有可能改錯(cuò)了配置文件,又得返工。這還是一個(gè)配置文件,如果數(shù)十個(gè)數(shù)百個(gè)呢?因此當(dāng)你學(xué)會(huì)了sed命令,你會(huì)發(fā)現(xiàn)利用它處理文件中的一系列修改是很有用的。只要想到在大約100多個(gè)文件中,處理20個(gè)不同的編輯操作可以在幾分鐘之內(nèi)完成,你就會(huì)知道sed的強(qiáng)大了。

2. 語法格式

sed [選項(xiàng)] [sed命令] [輸入文件]

說明:

1,注意sed軟件以及后面選項(xiàng),sed命令和輸入文件,每個(gè)元素之間都至少有一個(gè)空格。

2,sed -commands(sed命令)是sed軟件內(nèi)置的一些命令選項(xiàng),為了和前面的options(選項(xiàng))區(qū)分,故稱為sed命令

3,sed -commands 既可以是單個(gè)sed命令,也可以是多個(gè)sed命令組合。

4,input -file (輸入文件)是可選項(xiàng),sed還能夠從標(biāo)準(zhǔn)輸入如管道獲取輸入。

3. sed的工作原理

sed讀取一行,首先將這行放入到緩存中

然后,才對(duì)這行進(jìn)行處理

處理完成以后,將緩沖區(qū)的內(nèi)容發(fā)送到終端

存儲(chǔ)sed讀取到的內(nèi)容的緩存區(qū)空間稱之為:模式空間(Pattern Space)

4. 選項(xiàng)說明

option[選項(xiàng)] 解釋說明(帶*的為重點(diǎn))
-n (no) 取消默認(rèn)的sed軟件的輸出,常與sed命令的p連用。*
-e (entry) 一行命令語句可以執(zhí)行多條sed命令 *
-r (ruguler) 使用擴(kuò)展正則表達(dá)式,默認(rèn)情況sed只識(shí)別基本正則表達(dá)式 *
-i (inside) 直接修改文件內(nèi)容,而不是輸出到終端,如果不使用-i選項(xiàng)sed軟件只是修改在內(nèi)存中的數(shù)據(jù),并不會(huì)影響磁盤上的文件*
sed -commands[sed命令] 解釋說明(帶*的為重點(diǎn))
a (append) 追加,在指定行后添加一行或多行文本 *
c (change) 取代指定的行
d (delete) 刪除指定的行 * `
i (insert) 插入,在指定行前添加一行或多行文本 *
p (print) 打印模式空間內(nèi)容,通常p會(huì)與選項(xiàng)-n一起使用*
特殊符號(hào) 解釋說明(帶*的為重點(diǎn))
! 對(duì)指定行以外的所有行應(yīng)用命令*

sed.增.刪.改.查

1. 增

這里我們需要用到2個(gè)sed命令,分別是:

  • “a”:追加文本到指定行后,記憶方法:a的全拼是apend,意思是追加。
  • “i“:插入文本到指定行前,記憶方法:i的全拼是insert,意思是插入。

實(shí)例1:a

[root@ken ~]# sed "2a 這是新添加的一行" test
this is the first line
this is the second line
這是新添加的一行
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line
  1. 2代表指定對(duì)第2行操作,其他的行忽略
  2. a代表插入的意思,2i即在第2行前插入文本
  3. 2a后面加上空格,然后跟上你想要插入的文本即可

實(shí)例2:i

[root@ken ~]# sed "2i 我又新添加了一行" test
this is the first line
我又新添加了一行
this is the second line
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

實(shí)例3:同時(shí)增加多行(/n)

[root@ken ~]# sed "2i 這是第一條記錄\n這是第二條記錄\n這是第三條記錄" test
this is the first line
這是第一條記錄
這是第二條記錄
這是第三條記錄
this is the second line
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

2.刪

  • 這個(gè)功能也是非常得有用,比如我們想刪除文件中的某些行,以前最常用的是vi或vim命令,但現(xiàn)在我們知道了sed命令,就應(yīng)該使用這個(gè)高逼格的命令完成任務(wù)了。
  • “d”:刪除文本,記憶方法:d的全拼是delete,意思是刪除。
  • sed軟件可以對(duì)單行或多行文本進(jìn)行處理。如果在sed命令前面不指定地址范圍,那么默認(rèn)會(huì)匹配所有行。

實(shí)例1:刪除所有的行

[root@ken ~]# cp test{,.bak}
[root@ken ~]# sed 'd' test

命令說明:如果在sed命令前面不指定地址范圍,那么默認(rèn)會(huì)匹配所有行,然后使用d命令刪除功能就會(huì)刪除這個(gè)文件的所有內(nèi)容

實(shí)例2:刪除指定的行

[root@ken ~]# cat test.bak >test
[root@ken ~]# sed '2d' test
this is the first line
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

實(shí)例3:刪除指定范圍行

[root@ken ~]# sed '2,5d' test
this is the first line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

實(shí)例4:刪除匹配的行

[root@ken ~]# sed '/sixth/d' test
this is the first line
this is the second line
this is the third line
this is the forth line
this is the fivth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line

命令說明:在sed軟件中,使用正則的格式和awk一樣,使用2個(gè)”/“包含指定的正則表達(dá)式,即“/正則表達(dá)式/”。

實(shí)例5:刪除指定行到行尾的內(nèi)容

[root@ken ~]# sed '2,$d' test
this is the first line

第二行也會(huì)被刪掉

實(shí)例6:取反

一、

[root@ken ~]# sed '2,3!d' test
this is the second line
this is the third line

二、

[root@ken ~]# sed '/tenth/!d' test
this is the tenth line

3.改

  • “c”:用新行取代舊行,記憶方法:c的全拼是change,意思是替換。
[root@ken ~]# sed '2c 改過之后的第二行' test
this is the first line
改過之后的第二行
this is the third line
this is the forth line
this is the fivth line
this is the sixth line
this is the seventh line
this is the eighth line
this is the ninth line
this is the tenth line
this is sixth line

文本替換

  • 接下來說的這個(gè)功能,有工作經(jīng)驗(yàn)的同學(xué)應(yīng)該非常的熟悉,因?yàn)槭褂胹ed軟件80%的場(chǎng)景就是使用替換功能。
  • 這里用到的sed命令,選項(xiàng):
    “s”:單獨(dú)使用–>將每一行中第一處匹配的字符串進(jìn)行替換==>sed命令
    “g”:每一行進(jìn)行全部替換–>sed命令s的替換標(biāo)志之一(全局替換),非sed命令。
    “-i”:修改文件內(nèi)容–>sed軟件的選項(xiàng),注意和sed命令i區(qū)別。

sed軟件替換模型

sed -i ‘s/目標(biāo)內(nèi)容/替換內(nèi)容/g’ ken.log
sed -i ‘s#目標(biāo)內(nèi)容#替換內(nèi)容#g’

實(shí)例1:

[root@ken ~]# sed 's/line/hang/g' test
this is the first hang
this is the second hang
this is the third hang
this is the forth hang
this is the fivth hang
this is the sixth hang
this is the seventh hang
this is the eighth hang
this is the ninth hang
this is the tenth hang
this is sixth hang

命令說明:從上面命令的結(jié)果我們就知道sed命令默認(rèn)不會(huì)修改文件的內(nèi)容

實(shí)例2:

[root@ken ~]# sed -i 's/line/hang/g' test
[root@ken ~]# cat test
this is the first hang
this is the second hang
this is the third hang
this is the forth hang
this is the fivth hang
this is the sixth hang
this is the seventh hang
this is the eighth hang
this is the ninth hang
this is the tenth hang
this is sixth hang

命令說明:如果想真正的修改文件內(nèi)容,我們就需要使用選項(xiàng)“-i”,這個(gè)要和sed命令“i”區(qū)分開來。同時(shí)我們可以發(fā)現(xiàn)命令執(zhí)行后的結(jié)果是沒有任何輸出的。

4.查

  • 這個(gè)功能也是非常得有用,比如我們想查看文件中的某些行,以前最常用的是cat或more或less命令等,但這些命令有些缺點(diǎn),就是不能查看指定的行。而我們用了很久的sed命令就有了這個(gè)功能了。而且我們前面也說過使用sed比其他命令vim等讀取速度更快!
  • 這里我們需要用到1個(gè)sed命令
  • “p”:輸出指定內(nèi)容,但默認(rèn)會(huì)輸出2次匹配的結(jié)果,因此使用-n選項(xiàng)取消默認(rèn)輸出,記憶方法:p的全拼是print,意思是打印。

實(shí)例1:

[root@ken ~]# sed '2p' test
this is the first hang
this is the second hang
this is the second hang
this is the third hang
this is the forth hang
this is the fivth hang
this is the sixth hang
this is the seventh hang
this is the eighth hang
this is the ninth hang
this is the tenth hang
this is sixth hang
[root@ken ~]# sed -n '2p' test
this is the second hang

實(shí)例2:

[root@ken ~]# sed -n '2,5p' test
this is the second hang
this is the third hang
this is the forth hang
this is the fivth hang

實(shí)例3:

[root@ken ~]# sed -n '/ninth/p' test
this is the ninth hang

補(bǔ)充:-e多點(diǎn)操作

實(shí)例1:

[root@ken ~]# sed -e '2d' -e '5d' test
this is the first hang
this is the third hang
this is the forth hang
this is the sixth hang
this is the seventh hang
this is the eighth hang
this is the ninth hang
this is the tenth hang
this is sixth hang

實(shí)例2:

[root@ken ~]# sed -n -e '2p' -e '5p' test
this is the second hang
this is the fivth hang

刪除注釋行和空白行

第一種方法:

[root@ken ~]# cp test{,.bak}
[root@ken ~]# ls
anaconda-ks.cfg a.out ken1 test test1 test2 test.bak test.txt
[root@ken ~]# grep -v -E “(^$)|(^#)” test.bak
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
i#adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
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
operator:x:11:0:operator:/root:/sbin/nologin
[root@ken ~]# grep -v -E “(^$)|(^#)” test.bak > test
[root@ken ~]# cat test
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
i#adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
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
operator:x:11:0:operator:/root:/sbin/nologin

第二種方法:

[root@ken ~]# sed -i -e ‘/^$/d’ -e ‘/^#/d’ test.bak
[root@ken ~]# cat test.bak
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
i#adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
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
operator:x:11:0:operator:/root:/sbin/nologin

sed用法總結(jié)

1.查找指定的字符串

例子:顯示/etc/passwd中保含root的行(顯示模式空間中的內(nèi)容)

方法1:set '/root/p' /etc/passwd

方法2:cat /etc/passwd | sed '/root/p'</pre>

2.在指定的位置做增刪

例子:刪除以root為開頭的行

# sed ‘/^root/d’ a.txt

例子:在包含root的行后添加一行 i am ken

# sed ‘/root/a i am ken’ a.txt

3.按行替換

例子:將5到9行的內(nèi)容替換為 i am ken

# sed ‘5,9c i am ken’ a.txt

4.按照字符替換

例子:將/etc/selinux/config中的SELINUX=enforcing改成 disabled

寫法1:# sed -i ‘s/SELINUX=disabled/SELINUX=enforcing/g’ config

寫法2:# sed -r -i ‘s/(SELINUX=)disabled/\1enforcing/g’ config

5.查找指定的內(nèi)容再做替換

例子:將以r開頭的行中的oo替換為qq

# sed ‘/^r/{s/oo/qq/g}’ passwd

6.多點(diǎn)編輯

例子:去除文件中的注釋行和空白行

# grep -v -E “(^#)|(^$)” passwd.bak >passwd

# cat passwd.bak | sed -e ‘/^#/d’ -e ‘/^$/d’ >passwd

7)取反操作

顯示非1-3行

# sed -n ‘1,3!p’ passwd

awk詳解

awk不僅僅時(shí)linux系統(tǒng)中的一個(gè)命令,而且是一種編程語言,可以用來處理數(shù)據(jù)和生成報(bào)告(excel)。處理的數(shù)據(jù)可以是一個(gè)或多個(gè)文件,可以是來自標(biāo)準(zhǔn)輸入,也可以通過管道獲取標(biāo)準(zhǔn)輸入,awk可以在命令行上直接編輯命令進(jìn)行操作,也可以編寫成awk程序來進(jìn)行更為復(fù)雜的運(yùn)用。

awk的格式

  • awk指令是由模式,動(dòng)作,或者模式和動(dòng)作的組合組成。
  • 模式既pattern,可以類似理解成sed的模式匹配,可以由表達(dá)式組成,也可以是兩個(gè)正斜杠之間的正則表達(dá)式。比如NR==1,這就是模式,可以把他理解為一個(gè)條件。
  • 動(dòng)作即action,是由在大括號(hào)里面的一條或多條語句組成,語句之間使用分號(hào)隔開。比如awk使用格式:
image

awk處理的內(nèi)容可以來自標(biāo)準(zhǔn)輸入(<),一個(gè)或多個(gè)文本文件或管道。

image
  • pattern既模式,也可以理解為條件,也叫找誰,你找誰?高矮,胖瘦,男女?都是條件,既模式。
  • action既動(dòng)作,可以理解為干啥,找到人之后你要做什么。
    模式和動(dòng)作的詳細(xì)介紹我們放在后面部分,現(xiàn)在大家先對(duì)awk結(jié)構(gòu)有一個(gè)了解。
  • 分析awk處理過程:

讀取文本第一行,首先會(huì)和匹配模式進(jìn)行相匹配,如果發(fā)現(xiàn)第一行內(nèi)容不和模式相匹配的話,就繼續(xù)讀取下一行
讀取到第二行發(fā)現(xiàn)和模式相匹配,就會(huì)執(zhí)行花括號(hào)里面的動(dòng)作
然后繼續(xù)讀取下一行,發(fā)現(xiàn)和模式相匹配,就會(huì)執(zhí)行花括號(hào)里面的動(dòng)作
...
依次讀取全文

awk參數(shù)

-F:指定分隔符

幾個(gè)小概念

記錄(record):一行就是一個(gè)記錄

分隔符(field separator):進(jìn)行對(duì)記錄進(jìn)行切割的時(shí)候所使用的字符

字段(field):將一條記錄分割成的每一段

FILENAME:當(dāng)前處理文件的文件名

FS(Field Separator):字段分隔符(默認(rèn)是以空格為分隔符=)

NR(Number of Rrecord):記錄的編號(hào)(awk每讀取一行,NR就加1==)

NF(Number of Field):字段數(shù)量(記錄了當(dāng)前這條記錄包含多少個(gè)字段==)

ORS(Output Record Separator):指定輸出記錄分隔符(指定在輸出結(jié)果中記錄末尾是什么,默認(rèn)是\n,也就是換行)

OFS(Output Field Separator):輸出字段分隔符

RS:記錄分隔符

輸出字段的表示方式

$1 $2 … $n 輸出一個(gè)指定的字段

$NF 輸出最后一個(gè)字段

$0 輸出整條記錄

awk執(zhí)行過程

[root@ken ~]# awk 'NR>=2&&NR<=5{print $0}' /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/nologin

命令說明: 條件NR>=2,表示行號(hào)大于等于2時(shí)候,執(zhí)行{print $0}顯示整行。 awk是通過一行一行的處理文件,這條命令中包含模式部分(條件)和動(dòng)作部分(動(dòng)作),awk將處理模式(條件)指定的行

1)awk讀入第一行內(nèi)容

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

a,如果匹配則執(zhí)行對(duì)應(yīng)的動(dòng)作{print $0}
b,如果不匹配條件,繼續(xù)讀取下一行

3)繼續(xù)讀取下一行
4)重復(fù)過程1-3,直到讀取到最后一行(EOF:end of file)

準(zhǔn)備測(cè)試文件

[root@ken ~]# head /etc/passwd > test
[root@ken ~]# cat test
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
operator:x:11:0:operator:/root:/sbin/nologin

實(shí)例1:打印行號(hào)

[root@ken ~]# awk '{print NR,$0}' test
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 operator:x:11:0:operator:/root:/sbin/nologin

實(shí)例2:輸出有多余5個(gè)字段的行的第三個(gè)字段

[root@ken ~]# awk -F ':' 'NF>=5{print $3}' test
0
1
2
3
4
5
6
7
8
11

實(shí)例3:輸出每行行號(hào)和該行有幾個(gè)字段

[root@ken ~]# awk -F ':' '{print NR,NF}' test
1 7
2 7
3 7
4 7
5 7
6 7
7 7
8 7
9 7
10 7

例子4:打印出來用戶名以及對(duì)應(yīng)的shell類型

[root@ken ~]# awk -F “:” ‘{print $1,$NF}’ test
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
i#adm /sbin/nologin
lp /sbin/nologin
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin

[root@ken ~]# awk -F “:” ‘{print $1,$7}’ test
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
i#adm /sbin/nologin
lp /sbin/nologin
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin

awk進(jìn)階–正則

  • 正則表達(dá)式的運(yùn)用,默認(rèn)是在行內(nèi)查找匹配的字符串,若有匹配則執(zhí)行action操作,但是有時(shí)候僅需要固定的列來匹配指定的正則表達(dá)式,比如:我想取/etc/passwd文件中第五列{$5}這一列查找匹配mail字符串的行,這樣就需要用另外兩個(gè)匹配操作符,并且awk里面只有這兩個(gè)操作符來匹配正則表達(dá)式。

實(shí)例1:匹配整行

[root@ken ~]# awk '/^root/' test
root:x:0:0:root:/root:/bin/bash

和下面的效果是一樣的

[root@ken ~]# awk '$0~/^root/' test
root:x:0:0:root:/root:/bin/bash

注意:awk只用正則表達(dá)式的時(shí)候是默認(rèn)匹配整行的即‘$0~/root/’和‘/root/’是一樣的。

實(shí)例2:匹配一行中的某一列

[root@ken ~]# awk -F ':' '$5~/root/' test
root:x:0:0:root:/root:/bin/bash

提示:

  • $5表示第五個(gè)區(qū)域(列)
  • ~表示匹配(正則表達(dá)式匹配)
  • /root/表示匹配root這個(gè)字符串

$5~/root/表示第五個(gè)區(qū)域(列)匹配正則表達(dá)式/root/,既第5列包含root這個(gè)字符串,則顯示這一行。

實(shí)例3:匹配行尾為sync

[root@ken ~]# awk -F ':' '/sync$/{print $0}' test
sync:x:5:0:sync:/sbin:/bin/sync

實(shí)例4:顯示名字和登錄類型

[root@ken ~]# awk -F ':' '{print $1,$NF}' test
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin

$NF:表示匹配的末尾部分,這里也可以寫成$7

實(shí)戰(zhàn): 取出網(wǎng)卡IP地址(企業(yè)面試題)

[root@ken ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether 00:0c:29:99:ea:a6 brd ff:ff:ff:ff:ff:ff
    inet 172.20.10.6/24 brd 172.20.10.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 2408:84f4:86:47e1:20c:29ff:fe99:eaa6/64 scope global mngtmpaddr dynamic 
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe99:eaa6/64 scope link 
       valid_lft forever preferred_lft forever

第一種方法:

[root@ken ~]# ip a | awk -F ' +' 'NR==9{print $3}' | awk -F '/' '{print $1}'
172.20.10.6

第二種方法:

[root@ken ~]# ip a | grep -E '^ +.*inet\>.*' | awk -F ' +|/' 'NR==2{print $3}'
172.20.10.6

第三種方法:

[root@ken ~]# hostname -i | awk -F ' ' '{print $3}'
172.20.10.6

第四種方法:

[root@ken ~]# ip a | grep brd.*glo | awk -F ' +|/' '{print $3}'
172.20.10.6

第五種方法:

[root@ken ~]# ip a | grep "scope" | awk 'NR==3{print $0}' | awk -F "( |/)+" '{print $3}'
172.20.10.6

方法還有很多很多,大家如果對(duì)自己有高要求的話,要至少寫出來十種以上的方法哦!

awk特殊模式-BEGIN模式與END模式

  • BEGIN模塊再awk讀取文件之前就執(zhí)行,一般用來定義我們的內(nèi)置變量(預(yù)定義變量,eg:FS,RS)
  • 需要注意的是BEGIN模式后面要接跟一個(gè)action操作塊,包含在大括號(hào)內(nèi)。awk必須在輸入文件進(jìn)行任何處理前先執(zhí)行BEGIN里的動(dòng)作(action)。我們可以不要任何輸入文件,就可以對(duì)BEGIN模塊進(jìn)行測(cè)試,因?yàn)閍wk需要先執(zhí)行完BEGIN模式,才對(duì)輸入文件做處理。BEGIN模式常常被用來修改內(nèi)置變量ORS,RS,F(xiàn)S,OFS等值。

BEGIN模塊

實(shí)例1:

[root@ken ~]# ifconfig eth0 | awk -F "[ :]+" 'NR==2{print $3}'
172.20.10.6
[root@ken ~]# ifconfig eth0 | awk -F "[^0-9.]+" 'NR==2{print $2}'
172.20.10.6

#上面的也可以寫成
[root@ken ~]# ifconfig eth0 | awk 'BEGIN{FS="[ :]+"}NR==2{print $3}'
172.20.10.6
[root@ken ~]# ifconfig eth0 | awk 'BEGIN{FS="[^0-9.]+"}NR==2{print $2}'
172.20.10.6

實(shí)例2:在讀取文件之前,輸出些提示性信息(表頭)。

[root@ken ~]# awk -F ':' 'BEGIN{print "username","bash type"}{print $1,$NF}' test
username bash type
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin

END模塊

EHD在awk讀取完所有的文件的時(shí)候,再執(zhí)行END模塊,一般用來輸出一個(gè)結(jié)果(累加,數(shù)組結(jié)果),也可以是和BEGIN模塊類似的結(jié)尾標(biāo)識(shí)信息與BEGIN模式相對(duì)應(yīng)的END模式,格式一樣,但是END模式僅在awk處理完所有輸入行后才進(jìn)行處理。

實(shí)例1:

[root@ken ~]# awk -F ':' 'BEGIN{print "username","bash type"}{print $1,$NF}END{print "end of file"}' test
username bash type
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
end of file

實(shí)例2:統(tǒng)計(jì)包含root的行的數(shù)量

方法一:

[root@ken ~]# cat test | grep root| wc -l
2

方法二:

[root@ken ~]# cat test | grep -c root
2

方法三:

[root@ken ~]# cat /etc/passwd | awk 'BEGIN{i=0}/root/{i++}END{print i}'
2
[root@ken ~]# cat /etc/passwd | awk '/root/{i++}END{print i}'
2

總結(jié)awk執(zhí)行過程

回顧一下awk的結(jié)構(gòu)

awk -F 指定分隔符 ‘BRGIN{}END{}’,如下圖

image

awk數(shù)組

數(shù)組構(gòu)成:

數(shù)組名[元素名]=值

image

如圖不難發(fā)現(xiàn),awk數(shù)組就和酒店一樣。數(shù)組的名稱就像是酒店名稱,數(shù)組元素名稱就像酒店房間號(hào)碼,每個(gè)數(shù)組元素里面的內(nèi)容就像是酒店房間里面的人。

實(shí)戰(zhàn):統(tǒng)計(jì)域名出現(xiàn)的次數(shù)(百度和搜狐面試題)

[root@ken ~]# cat test
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken

方法一:

[root@ken ~]# cat test | awk -F '/+' '{print $2}' | sort | uniq -c
      7 www.qq.com
     13 www.sina.com
     25 www.taobao.com</pre>

方法二:

[root@ken ~]# cat test | awk -F '/+' '{h[$2]++}END{for (i in h) print i,h[i]}'
www.sina.com 13
www.qq.com 7
www.taobao.com 25

awk用法總結(jié)

1. **結(jié)合內(nèi)置變量,打印指定的幾行,以及字段數(shù)量**

例子;輸出有多余5個(gè)字段的行的第三個(gè)字段

# cat a.sh | awk -F “:” ‘NF>=5{print $3}’

例子:輸出每行行號(hào)和該行有幾個(gè)字段

# cat a.sh | awk -F “:” ‘{print NR,NF}’

例子:輸出用戶名,要求所有用戶顯示在同一行,而且用空格分隔

# cat mypwd | awk ‘BEGIN{FS=”:”; ORS=” “}{print $1}’

2. **結(jié)合正則來匹配一行或者某個(gè)字段**

例子:輸出用戶名以s為開頭的用戶的uid

# cat mypwd | awk -F “:” ‘/^s/{print $}’

例子:輸出第五個(gè)字段是以t為結(jié)尾的用戶的姓名

# cat mypwd | awk -F “:” ‘$5~/t$/{print $1}’

3. **采用比較符號(hào)來進(jìn)行打印指定的某些行**

例子:實(shí)現(xiàn)僅僅輸出3-5的內(nèi)容,每行前面添加一個(gè)行號(hào)

# cat mypwd | awk ‘NR>=3&&NR<=5{print NR,$1}’

或

# cat mypwd | awk ‘NR==3,NR==5{print NR,$1}’

例子:實(shí)現(xiàn)僅僅輸出3 和 5 和 7行的內(nèi)容,每行前面添加一個(gè)行號(hào)

# cat mypwd | awk ‘NR==3||NR==5||NR==7{print NR,$1}’

4. **END**

例子:統(tǒng)計(jì)mypwd中以#開頭的行有多少行

# cat mypwd | awk ‘BEGIN{n=0}/^#/{n+=1}END{print n}’

統(tǒng)計(jì):mypwd中,以:為分隔符,字段數(shù)量在3-5的行的數(shù)目

# cat mypwd  | awk ‘BEGIN{FS=”:”}NF>=3&&NF<=5{n+=1}END{print n}’

5. **ip**

例子:統(tǒng)計(jì)IP

[root@ken]# cat url.txt | awk -F “/+” ‘{urls[$2]++}END{for(key in urls)print key, urls[key]}’

www.baidu.com 12

haha.baidu.com 1

ftp.baidu.com 6

mail.baidu.com 7
最后編輯于
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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