筆記7 正則(grep、sed、awk工具)
含義:就是一串有規律的字符串
掌握好正則對於編寫shell腳本有很大幫助
各種編程語言中都有正則,原理是一樣的
本章將要學習grep/egrep、sed、awk
grep
用來過濾指定關鍵詞的
創建一個實驗環境,創建mkdir grep;進入cd grep;拷貝cp /etc/passwd grep
格式:grep後邊跟關鍵詞在跟文件名
-c 顯示行數
-i 不區分大小寫,加上-i它會把大寫的顯示出來
-n 顯示行號
-v 取反,意思就是把你指的關鍵詞之外的全顯示出來,例如我一開始指定要帶nologin的,加上-v之後就會顯示不帶有它的,如圖。
-r 把一些子目錄或者孫目錄所有下邊的文件遍歷一遍
-A後面跟數字,過濾出符合要求的行以及下面的n行,意思就是比如你要過濾關鍵詞root,加上-A2,它會給你把只要有root關鍵詞的這一行加上往下的兩行一起列出來,如下圖。
-B跟A相反,過濾出符合要求的行以及上面的n行
-C全是AB的結合,過濾出符合要求的行以及上下各n行
grep '[0-9]' 表示過濾0-9的數字,例如,grep ’[0-9]' passwd 如下圖
grep -n '^#' ^以什麽開頭的,意思是以#號開頭的行
grep -vn '^#' 意思是不以#號開頭的行
grep '[^0-9]' 把裏邊非0-9的列出來
grep '^[^0-9]' 當^放到[]裏面時,他就是取反的意思,以一個非數字開頭的行全部列出來
grep -v '^[^0-9]'相反的行
grep 'r.o' .表示任意的一個字符,不管是a-z,A-Z,0-9,還是特殊符號都能匹配到
grep 'o*o' *表示0個過多個*前面的字符,0次也算,跟+號相似+號是1次或多次
grep '.*' 表示任意一個任意字符,都匹配
單獨匹配一行
grep 'o\{2\}' 一樣的命令還有egrep 'o{2}' grep -E 'o{2}'花括號表示前面這個字符的重復範圍
egrep -n '(oo){2}' passwd
egrep 'o+o'或grep 'o\+o' passwd +意思是一個或多個加號前邊的字符,0次不算。跟*號相似,*是0次或者多次。
egrep 'o?t' ?表示零個或一個問號前邊的字符,要麽有一次要麽就沒有,有就是ot沒有就是t
grep -E 'root|nologin' passwd 豎線是或者的意思,只要有root的或則nologin的都會匹配,
或者用egrep 'root|nologin' passwd
sed
匹配指定的字符
sed -n 只匹配一個指定字符例如,sed -n '/root/'p test.txt 只匹配有root字符的行
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
特性:sed -e '1'p -e '/root/'p -n test.txt
在p後邊加上大I就不會區分大小寫了sed -e '1'p -e '/bus/'Ip -n test.txt
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 如下圖
刪除英文字母:sed 's/[a-zA-Z]//g'如下圖,head test.txt | sed 's/[a-zA-Z]//g'
出現兩個//時它會報錯我們需要加上\,例如:sed 's//root/123/g'換成sed 's/\/root/123/g' 如下圖:
在所有的行前面加上一個固定的字符串如下圖:sed -r 's/(.*)/aaa:&/' test.txt
如何把第一段和最後一段調換位置,如下圖:
awk
把第一段打印出來:awk -F ‘:’ ‘{print $1}’ test.txt 如下圖:
打印所有的段用0表示:awk ‘:’ ‘{print $0}’ test.txt
打印指定更多的段:awk -F ‘:’ ‘{print $1,$2,$3}’ test.txt
列出指定的字符,例如oo:awk ‘oo' test.txt
只要第一段帶oo的:awk -F ‘:’ ‘$1 ~ /oo/’ .test.txt
多個表達式一起寫:awk -F ':' '/root/ {print $1,$3} /test/ {print $1,$3}' /etc/passwd
查找第三段等於0行:awk -F ':' '$3=="0"' /etc/passwd
查找某一段大於等於500的:awk -F ':' '$3>="500"' /etc/passwd
!=意思就是不等於:awk -F ':' '$7!="/sbin/nologin"' /etc/passwd
還可以把第幾段小於第幾段的列出來:awk -F ‘$3<$4’
相等的段也可以列出來:awk -F ‘$3=$4’
還可以把一段大於幾並且小於幾的一同列出來:awk -F ‘$3>“5” && $3<“7”’
||是或者的意思:awk -F ':' '$3>"5" || $7=="/bin/bash"' /etc/passwd
OFS是在你打印的時候指定的分隔符。例如:
awk -F ‘:’ ‘{OFS=“#”}{if ($3>1000) {print $1,$2,$3,$4}’
NR表示打印時的行:awk -F ':' '{print NR“:”$0}' 顯示行號的意思,把所有的行打印出來。
NF表示打印是的段:awk -F ':' '{print NF“:”$0}'
只要前十行:awk -F ‘:’ ‘NR<=10’
計算某個段落的總和:awk -F ':' '{(tot=tot+$3)}; END {print tot}' /etc/passwd END表示所有的行都已經執行。
筆記7 正則(grep、sed、awk工具)