筆記7 正則(grep、sed、awk工具)

正則
含義:就是一串有規律的字符串shell

掌握好正則對於編寫shell腳本有很大幫助編程

各類編程語言中都有正則,原理是同樣的
bash

本章將要學習grep/egrep、sed、awk
編程語言


grepide

用來過濾指定關鍵詞的post

建立一個實驗環境,建立mkdir grep;進入cd grep;拷貝cp /etc/passwd grep
格式:grep後邊跟關鍵詞在跟文件名
-c 顯示行數學習

wKiom1lvC2LgmxC4AABo8JX5rWk203.png

-i 不區分大小寫,加上-i它會把大寫的顯示出來
wKiom1lvC-WwitV0AAGe8UhQagI575.pngspa

-n 顯示行號3d

wKiom1lvC5fCDWHUAAGpGO-rTT4443.png

-v 取反,意思就是把你指的關鍵詞以外的全顯示出來,例如我一開始指定要帶nologin的,加上-v以後就會顯示不帶有它的,如圖。blog

wKioL1lvDCHzRjhZAAFrOGMuoUo840.png

-r 把一些子目錄或者孫目錄全部下邊的文件遍歷一遍
-A後面跟數字,過濾出符合要求的行以及下面的n行,意思就是好比你要過濾關鍵詞root,加上-A2,它會給你把只要有root關鍵詞的這一行加上往下的兩行一塊兒列出來,以下圖。

wKioL1lvDJnSF6odAAFQMCKEbZg144.png

-B跟A相反,過濾出符合要求的行以及上面的n行

wKioL1lvDLGCeCFMAAEq2Cozq3o047.png

-C全是AB的結合,過濾出符合要求的行以及上下各n行

wKioL1lvDMHh4S4yAAFIZ7RjFcw397.png


grep '[0-9]' 表示過濾0-9的數字,例如,grep ’[0-9]' passwd 以下圖

wKioL1lvLDXQqzc0AAE484T8yEk064.png

 grep -n '^#'   ^以什麼開頭的,意思是以#號開頭的行

wKioL1lvLMCB8v_sAAEl0WEOrT0437.png

 grep -vn '^#' 意思是不以#號開頭的行

wKioL1lvLO-BynywAACcHIJ2eso629.png

 grep '[^0-9]'  把裏邊非0-9的列出來

wKioL1lvLRDxOxtNAABr6M2-Rco021.png

 grep '^[^0-9]'  當^放到[]裏面時,他就是取反的意思,以一個非數字開頭的行所有列出來

wKiom1lvLWLBoEzEAACH0JZdI-I583.png

 grep  -v '^[^0-9]'相反的行

wKiom1lvLX-BtwZhAAARLS0oXtI108.png 

grep 'r.o'  .表示任意的一個字符,無論是a-z,A-Z,0-9,仍是特殊符號都能匹配到

wKiom1lvLaChDY0VAADJ7tNyGIc694.png

 grep 'o*o' *表示0個過多個*前面的字符,0次也算,跟+號類似+號是1次或屢次

wKioL1lvLcPx1BVKAAGVOVQaZBg538.png

 grep '.*' 表示任意一個任意字符,都匹配

image.png

單獨匹配一行

image.png


grep 'o\{2\}' 同樣的命令還有egrep 'o{2}'   grep  -E 'o{2}'花括號表示前面這個字符的重複範圍

image.png

wKioL1lvLfiQpO8IAAINvRVZaKo007.png

egrep -n '(oo){2}' passwd

image.png


 egrep 'o+o'或grep 'o\+o' passwd        +意思是一個或多個加號前邊的字符,0次不算。跟*號類似,*是0次或者屢次。

image.png

image.png

 

egrep 'o?t'  ?表示零個或一個問號前邊的字符,要麼有一次要麼就沒有,有就是ot沒有就是t

image.png

wKiom1lvLkSj5qIDAACuR51K2aw150.png

 

grep -E 'root|nologin' passwd 豎線是或者的意思,只要有root的或則nologin的都會匹配,

或者用egrep 'root|nologin' passwd

wKioL1lvLlHgcCvjAAGjUw-4f-M981.png



sed

匹配指定的字符

sed -n 只匹配一個指定字符例如,sed -n '/root/'p test.txt  只匹配有root字符的行

image.png

sed -r 加上r以後就不用拖意了,例如,sed -nr '/o+t/'p test.txt

[root@aaa-01 sed]# sed -nr '/o+t/'p test.txt
root:x:0:0:root:/root:/bin/bash
operatoooooor:x:11:0:operator:/root:/sbin/nologin

sed -nr '/o{2}/'p test.txt匹配兩次o

[root@aaa-01 sed]# sed -nr '/o{2}/'p test.txt
root:x:0:0:root:/root:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operatoooooor:x:11:0:operator:/root:/sbin/nologin

或者:sed -nr '/root|bus/'p test.txt

[root@aaa-01 sed]# sed -nr '/root|bus/'p test.txt
root:x:0:0:root:/root:/bin/bash
operatoooooor:x:11:0:operator:/root:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin


指定打印的行p

sed -n '5'p test.txt  打印指定的行

[root@aaa-01 sed]# sed -n '5'p test.txt
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

sed -n '1,5'p test.txt 打印指定範圍的行

[root@aaa-01 sed]# sed -n '1,5'p test.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

sed -n '20,$'p test.txt 打印指定的行到末尾的行,$末尾行的意思1,&是所有打印出來

[root@aaa-01 sed]# sed -n '20,$'p test.txt
awei:x:1000:1000::/home/awei:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1004:1003::/home/user3:/bin/bash
user4:x:1006:1003::/home/awei111:/sbin/nologin
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1010:1008::/home/user6:/bin/bash

打印指定的字符:例如只打印root的行,sed -n '/root/'p test.txt 

[root@aaa-01 sed]# sed -n '/root/'p test.txt 
root:x:0:0:root:/root:/bin/bash
operatoooooor:x:11:0:operator:/root:/sbin/nologin

以一個字符開頭的,例如以p開頭的行,sed -n '/^p/'p test.txt

[root@aaa-01 sed]# sed -n '/^p/'p test.txt
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin

sed -n 'in$'p test.txt

sed -n '/r..o/'p test.txt

sed -n 'oo*'p test.txt

sed -e '1'p -e '/111/'p -n test.txt

sed -e 在同一個表達式裏邊作多項操做,例如,我不只要把第一行打印出來還要匹配字符串awei,sed -e '1'p -e '/awei/'p -n test.txt 

image.png

特性:sed -e '1'p -e '/root/'p -n test.txt

image.png

 在p後邊加上大I就不會區分大小寫了sed -e '1'p -e '/bus/'Ip -n test.txt

image.png

image.png


d刪除指定的行
 sed '1,20'd test.txt 意思是把一到二十行刪除,可是他並無刪除,只是把剩下的行給列出來

[root@aaa-01 sed]# sed '1,20'd test.txt
awei:x:1000:1000::/home/awei:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1004:1003::/home/user3:/bin/bash
user4:x:1006:1003::/home/awei111:/sbin/nologin
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1010:1008::/home/user6:/bin/bash
[root@aaa-01 sed]# wc -l test.txt 
26 test.txt

 set -i 這個是刪除選項,例如刪除指定行sed -i '1,6'd test.txt

[root@aaa-01 sed]# sed -i '1,6'd test.txt
[root@aaa-01 sed]# wc -l test.txt
20 test.txt

刪除指定字符的行 例如:sed -i '/user5/'d test.txt

[root@aaa-01 sed]# sed -i '/user5/'d test.txt
[root@aaa-01 sed]# tail -n4 test.txt
awei:x:1000:1000::/home/awei:/bin/bash
user3:x:1004:1003::/home/user3:/bin/bash
user4:x:1006:1003::/home/awei111:/sbin/nologin
user6:x:1010:1008::/home/user6:/bin/bash


s替換指定的字符 

例如:

sed '1,10s/root/toor/g' test.txt  意思是把一到十行裏的root替換成toor 以下圖

wKiom1lwbevjRnY5AAFBJBEg9HY161.png

 刪除英文字母:sed 's/[a-zA-Z]//g'以下圖,head test.txt | sed 's/[a-zA-Z]//g'

wKiom1lwbhaSZ3RuAACTiM8THqY414.png

 出現兩個//時它會報錯咱們須要加上\,例如:sed 's//root/123/g'換成sed 's/\/root/123/g'  以下圖:

wKiom1lwbk2zsaSWAAFhARi_vMY433.png

 在全部的行前面加上一個固定的字符串以下圖:sed -r 's/(.*)/aaa:&/' test.txt

wKioL1lwbmDRKPpqAAFZ8LldBBQ211.png

 如何把第一段和最後一段調換位置,以下圖:

wKiom1lwb-DgFAWeAADRlILBnbI079.jpg

sed '/^\s*$/d' passwd 去除空行
sed 's/^[ \t]*//g' passwd 去除首行空格
sed 's/^[ ]*//g' passwd 
sed '/^[ ].*/'d passwd


awk

 把第一段打印出來:awk -F ':' '{print $1}' test.txt  以下圖:

wKiom1lwjxigKV9vAAB8H_4SzDM767.png

打印全部的段用0表示:awk '{print $0}' test.txt   不加-F選項他默認字符中的空格或者空白部分爲分隔符

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


打印指定更多的段:awk -F ':' '{print $1,$2,$3,$4}' test.txt

[root@aaa-01 awk]# awk -F ':' '{print $1,$2,$3,$4}' test.txt
root x 0 0
bin x 1 1
daemon x 2 2
adm x 3 4
lp x 4 7

打印指定更多的段而且用特殊符號給他分割:awk -F ':' '{print $1"#"$2"#"$3"#"$4}' test.txt

[root@aaa-01 awk]# awk -F ':' '{print $1"#"$2"#"$3"#"$4}' test.txt
root#x#0#0
bin#x#1#1
daemon#x#2#2
adm#x#3#4
lp#x#4#7


列出指定的字符的段,例如oo:awk '/oo/' test.txt

wKioL1lwj0XDzhnuAAFdvUz8Hg8352.png

只要第一段帶oo的:awk -F ':' '$1 ~/oo/' test.txt

wKiom1lwj12yH44sAACaJFb6XT4070.png

多個表達式一塊兒寫:awk -F ':' '/root/ {print $1,$3} /test/ {print $1,$3}' /etc/passwd


查找第三段等於0行:awk -F ':' '$3=="0"' test.txt 

[root@aaa-01 awk]# awk -F ':' '$3=="0"' test.txt
root:x:0:0:root:/root:/bin/bash

或者查找第三段等於零的行,而且只要第一段:

[root@aaa-01 awk]# awk -F ':' '$3=="0" {print $1}' test.txt
root


查找指定的段大於等於1000的:awk -F ':' '$3>=1000' test.txt

[root@aaa-01 awk]# awk -F ':' '$3>=1000' test.txt
awei:x:1000:1000::/home/awei:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1004:1003::/home/user3:/bin/bash
user4:x:1006:1003::/home/awei111:/sbin/nologin

查找某一段大於等於500的:awk -F ':' '$3>="500"' test.txt

!=意思就是不等於:awk -F ':' '$7!="/sbin/nologin"' test.txt

[root@aaa-01 awk]# awk -F ':' '$7!="/sbin/nologin"' test.txt
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
awei:x:1000:1000::/home/awei:/bin/bash


還能夠把第幾段小於第幾段的列出來:awk -F ':' '$3<$4' test.txt

image.png


相等的段也能夠列出來:awk -F ':' '$3==$4' test.txt

image.png

&&而且 還能夠把一段大於幾而且小於幾的一同列出來,;如第三段大於2而且小於6的列出來:awk -F ':' '$3>"2" && $3<"6"' test.txt

image.png


||或者:awk -F ':' '$3>1000 || $7=="/bin/bash"' test.txt

image.png

awk -F ':' '$3>1000 || $7 ~ "/sin/"' test.txt

image.png


OFS是在你打印的時候指定的分隔符。例如:awk -F ':' '{OFS="#"} {if ($3>1000) {print $1,$2,$3,$4}}' test.txt

wKiom1lxpfLDzNdOAAEQ4XgXKpU601.png

NR表示打印時的行:awk -F ':' '{print NR": "$0}' test.txt  顯示行號的意思,把全部的行打印出來。

wKioL1lxp7ihRAT-AAGXVfxCfBg727.png

NF表示打印是每一行有多少段:awk -F ':' '{print NF": "$0}' test.txt

wKioL1lxqLOwDZRdAAESabF6c4M025.png

只要前十行:awk -F ':' 'NR<=10' test.txt 

[root@aaa-01 awk]# awk -F ':' 'NR<=10' test.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

計算某個段落的總和:awk -F ':' '{(tot=tot+$3)}; END {print tot}' /etc/passwd END表示全部的行都已經執行。

相關文章
相關標籤/搜索