Shell腳本三劍客——Grep(進階版egrep)、Sed、Awk命令

Grep命令

1、基本正則表達式實例——查找特定字符

這裏我們就以存放本機所有用戶的/etc/passwd文件做實例

Demo1

[root@localhost ~]# grep -n "root" /etc/passwd      //-n表示顯示行號
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin

2、基本正則表達式實例——查找集合字符

有重複的字符時,可使用“[ ]”來進行集合匹配,每次只匹配“[ ]”中的一個字符。

Demo2

[root@localhost ~]# grep -n "[fn]tp" /etc/passwd
12:ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
27:ntp:x:38:38::/etc/ntp:/sbin/nologin

3、基本正則表達式實例——反向選擇

在“[ ]”中括號中添加“^”表示進行反向選擇(有一定的基礎的朋友肯定知道“^[ ]”表示定位行首,這裏“^”內外位置意思將完全不同。)

Demo3

[root@localhost ~]# grep -n "^[^root]" /etc/passwd       //匹配除了以root開頭的所有選項
2:bin:x:1:1:bin:/bin:/sbin/nologin
3:daemon:x:2:2:daemon:/sbin:/sbin/nologin
......
42:named:x:25:25:Named:/var/named:/sbin/nologin

4、基本正則表達式實例——轉義符

在正則表達式中一個元字符,所以在這裏需要用轉義字符“\”將具有特殊意義的字符轉化成普通字符。

Demo4

[root@localhost ~]# grep -n '\.$' test.txt 1:he was short and fat.
2:He was wearing a blue polo shirt with black pants. 3:The home of Football on BBC Sport online.
5:google is the best tools for search keyword.

5、基本正則表達式實例——查找任一字符&查找重複字符

在正則表達式中小數點(.)也是一個元字符,代表任意一個字符。

Demo5-1

[root@localhost ~]# grep -n "r..t" /etc/passwd        //(.)小數點這裏代表任一字符
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
12:ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

在上述結果中,“root”字符串“r..t”匹配規則。若想要查詢 oo、ooo、ooooo 等資料,則需要使用星號(*)元字符。但需要注意的是,“*”代表的是重複零個或多個前面的單字符。“o*”表示擁有零個(即爲空字符)或大於等於一個“o”的字符

Demo5-2

[root@localhost ~]# grep -n "oo*" /etc/passwd
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、基本正則表達式實例——查找連續字符範圍

例如,查找三到五個 o 的連續字符,這個時候就需要使用基礎正則表達式中的限定範圍的字符“{ }”。因爲“{ }”在 Shell 中具有特殊 意義,所以在使用“{ }”字符時,需要利用轉義字符“\”,將“{ }”字符轉換成普通字符。

Demo6

[root@localhost ~]# grep -n "0\{2,\}" /etc/passwd       //表示中間包含2以上o的字符串
11:games:x:12:100:games:/usr/games:/sbin/nologin
41:zhy:x:1000:1000:zhy:/home/zhy:/bin/bash

Egrep命令

此外,grep 命令僅支持基礎正則表達式,如果使用擴展正則表達式,需要使用 egrep 或 awk 命令。awk 命令在後面的進行講解,這裏我們直接使用 egrep 命令。egrep 命令與 grep 命令的用法基本相似。(grep命令能用的egrep命令同樣能夠使用)

擴展正則表達式元字符 作用
+ 作用:重複一個或者一個以上的前一個字符
作用:零個或者一個的前一個字符
| 作用:使用或者(or)的方式找出多個字符
() 作用:查找“組”字符串
()+ 作用:辨別多個重複的組

Demo演示

[root@localhost ~]# egrep -n "10+" /etc/passwd             //使用“+”擴展元字符
11:games:x:12:100:games:/usr/games:/sbin/nologin
31:qemu:x:107:107:qemu user:/:/sbin/nologin
41:zhy:x:1000:1000:zhy:/home/zhy:/bin/bash

[root@localhost ~]# egrep -n "10?" /etc/passwd             //使用“?”擴展元字符
2:bin:x:1:1:bin:/bin:/sbin/nologin
9:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10:operator:x:11:0:operator:/root:/sbin/nologin
11:games:x:12:100:games:/usr/games:/sbin/nologin

[root@localhost ~]# egrep -n 'root|zhy' /etc/passwd        //使用“|”擴展元字符
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
41:zhy:x:1000:1000:zhy:/home/zhy:/bin/bash

[root@localhost ~]# egrep -n '(f|n)tp' /etc/passwd        //使用“()”擴展元字符,可與“|”一起使用
12:ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
27:ntp:x:38:38::/etc/ntp:/sbin/nologin

Sed命令

sed是一個很好的文件處理工具,本身是一個管道命令,主要是以行爲單位進行處理,可以將數據行進行替換、刪除、新增、選取等特定工作

sed 的工作流程主要包括讀取、執行和顯示三個過程。

Ø 讀取:sed 從輸入流(文件、管道、標準輸入)中讀取一行內容並存儲到臨時的緩

衝區中(又稱模式空間,pattern space)。

Ø 執行:默認情況下,所有的 sed 命令都在模式空間中順序地執行,除非指定了行的地址,否則 sed 命令將會在所有的行上依次執行。

Ø 顯示:發送修改後的內容到輸出流。再發送數據後,模式空間將會被清空。

在所有的文件內容都被處理完成之前,上述過程將重複執行,直至所有內容被處理完。

注意: 默認情況下,所有的sed命令都是在模式空間中進行,並不會進行保存。

Sed命令格式

sed [選項] '操作' 參數

sed [選項] -f scriptfile 參數 // scriptfile 表示腳本文件

常用選項

-e :表示用指定命令或者腳本來處理輸入的文本文件。

-f :表示用指定的腳本文件來處理輸入的文本文件。

-h :顯示幫助。

-n:表示僅顯示處理後的結果。

-i:直接編輯文本文件。

常用的“操作”參數

a:增加,在當前行下面增加一行指定內容。

c:替換,將選定行替換爲指定內容。

d:刪除,刪除選定的行

i:插入,在選定行上面插入一行指定內容。

p:打印,其通常與“-n”選項一起使用

s:替換,替換指定字符。

y:字符轉換。

基本用法實例:

輸出所有,效果等同cat命令

[root@localhost ~]# sed -n 'p' /etc/passwd                //效果等同cat命令
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
......

輸出某一特定行,或者某一段行

[root@localhost ~]# sed -n '10p' /etc/passwd                   //輸出第10行內容
operator:x:11:0:operator:/root:/sbin/nologin

[root@localhost ~]# sed -n '2,4p' /etc/passwd                 //輸出2~4行內容
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

輸出所有奇數行

[root@localhost ~]# sed -n 'n;p' /etc/passwd                //輸出奇數行,偶數行爲p;n
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
halt:x:7:0:halt:/sbin:/sbin/halt
......

同樣,除了基本的使用方法,sed命令也可以結合正則表達式進行使用

輸出包含特定內容的行(和grep命令一樣,可以使用^、$來定位行首、行尾)

[root@localhost ~]# sed -n '/root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

輸出包含特定單詞的行

[root@localhost ~]# sed -n '/\<root\>/p' /etc/passwd           //\<  \>代表單詞邊界
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

替換符合條件的文本

sed 's/the/THE/' test.txt //將每行中的第一個the 替換爲 THE

sed 's/l/L/3' test.txt //將每行中的第 3 個l 替換爲L

sed 's/the/THE/g' test.txt //將文件中的所有the 替換爲THE

sed 's/o//g' test.txt //將文件中的所有o 刪除(替換爲空串)

sed 's/^/#/' test.txt //在每行行首插入#:號

sed '/the/s/^/#/' test.txt //在包含the 的每行行首插入#號

sed 's/$/EOF/' test.txt //在每行行尾插入字符串EOF

sed '3,5s/the/THE/g' test.txt //將第 3~5 行中的所有the 替換爲 THE

sed '/the/s/o/O/g' test.txt //將包含the 的所有行中的o 都替換爲 O

將文本進行遷移

sed '/the/{H;d};$G' test.txt //將包含the 的行遷移至文件末尾,{;}用於多個操作

sed '1,5{H;d};17G' test.txt //將第 1~5 行內容轉移至第 17 行後

sed '/the/w out.file' test.txt //將包含the 的行另存爲文件out.file

sed '/the/r /etc/hostname' test.txt //將文件/etc/hostname 的內容添加到包含the 的每行以後

sed '3aNew' test.txt //在第 3 行後插入一個新行,內容爲 New

sed '/the/aNew' test.txt //在包含the 的每行後插入一個新行,內容爲 New

sed '3aNew1\nNew2' test.txt //在第 3 行後插入多行內容,中間的\n 表示換行

AWK命令

AWK 是一種用於處理文本的編程語言工具。AWK 在很多方面類似於 shell 編程語言,儘管 AWK 具有完全屬於其本身的語法,是任何環境中現有的功能最強大的數據處理引擎之一。

基本結構

awk [選項] '模式或條件 {編輯命令}' 文件1 文件2 //過濾並輸出匹配內容

awk -f 腳本文件 文件1 文件2 //從腳本中調用,並輸出

基本使用實例

[root@localhost ~]# awk -F: '{print $1,$3}' /etc/passwd
//以“:”作爲分隔符,篩選出第一列和第三列的內容,並輸出(默認情況下字段的分隔符爲空格或者 tab 鍵)
root 0
bin 1
daemon 2
adm 3
......

特殊的內建變量(可直接引入使用)

FS:指定每行文本的字段分隔符,默認爲空格或製表位。

NF:當前處理的行的字段個數。

NR:當前處理的行的行號(序數)。

$0:當前處理的行的整行內容。

$n:當前處理行的第 n 個字段(第 n 列)。

FILENAME:被處理的文件名。

RS:數據記錄分隔,默認爲\n,即每行爲一條記錄。

按行對文本進行輸出

[root@localhost ~]# awk 'NR==2,NR==4{print}' /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

[root@localhost ~]# awk -F ":" 'NR==2,NR==4{print $1,$3}' /etc/passwd
//輸出第二行到第四行的第一列和第三列內容
bin 1
daemon 2
adm 3

[root@localhost ~]# awk '(NR==1)||(NR==4){print}' /etc/passwd
//輸出第一行和第四行內容
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin

輸出奇、偶行(在awk中可以使用邏輯操作符“&&”,表示“與”, “||”表示“或”,“!”表示“非”;還可以進行簡單的數學運算,如+、-、*、/、%、^分別 表示加、減、乘、除、取餘和乘方)

[root@localhost ~]# awk 'NR%2==1{print}' /etc/passwd        //輸出奇數行
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
......

[root@localhost ~]# awk 'NR%2==0{print}' /etc/passwd       //輸出偶數行
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
halt:x:7:0:halt:/sbin:/sbin/halt
......

輸出以root開頭的行

[root@localhost ~]# awk '/^root/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash

統計以/bin/bash結尾的行數

[root@localhost ~]# awk 'BEGIN {x=0} ; /\/bin\/bash$/{x++};END {print x}' /etc/passwd
2

統計以空行分隔的文本段落數:

[root@localhost opt]# vim name.txt
zhangsan:lisi:wangwu
zhaoliu:liuliu
heiba:heihei
[root@localhost opt]# awk 'BEGIN{RS=":"};END{print NR}' /opt/name.txt
5
//統計規則:遇到關鍵符號,折行

調用w 命令,並用來統計在線用戶數:

[root@localhost opt]# awk 'BEGIN {while ("w" | getline) n++;{print n-2}}'
1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章