三劍客之grep指令
一 grep介紹
grep指令主要用于過濾文本,grep家族如下
grep: 在檔案中全局查找指定的正規表達式,并列印所有包含該表達式的行
egrep:擴充的egrep,支援更多的正規表達式元字元
fgrep:固定grep(fixed grep),有時也被稱作快速(fast grep),它按字面解釋所有的字元
grep指令格式如下
grep [選項] PATTERN 檔案1 檔案2 ...
[[email protected] ~]# grep 'root' /etc/passwd
[[email protected] ~]# fgrep 'bash' /etc/passwd
找到: grep傳回的退出狀态為0
沒找到: grep傳回的退出狀态為1
找不到指定檔案: grep傳回的退出狀态為2
grep 指令的輸入可以來自标準輸入或管道,而不僅僅是檔案,例如:
二 選項
-n, --line-number 在過濾出的每一行前面加上它在檔案中的相對行号
-o, --only-matching 隻顯示比對的内容
-q, --quiet, --silent 靜默模式,沒有任何輸出,得用$?來判斷執行成功沒有,即有沒有過濾到想要的内容
--color 顔色
-i, --ignore-case 忽略大小寫
-A, --after-context=NUM 如果比對成功,則将比對行及其後n行一起列印出來
-B, --before-context=NUM 如果比對成功,則将比對行及其前n行一起列印出來
-C, --context=NUM 如果比對成功,則将比對行及其前後n行一起列印出來
-c, --count 如果比對成功,則将比對到的行數列印出來
-v, --invert-match 反向查找,隻顯示不比對的行
-w 比對單詞
-E 等于egrep,擴充
-l, --files-with-matches 如果比對成功,則隻将檔案名列印出來,失敗則不列印
通常-rl一起用,grep -rl 'root' /etc
-R, -r, --recursive 遞歸
案例:
1、-n # 過濾出所有帶有root的行并顯示行号
[[email protected] ~]# grep -n 'root' /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
2、-o # 過濾出所有的root并列印出來
[[email protected] ~]# grep -o 'root' /etc/passwd
root
root
root
root
3、-q # 靜默模式
[[email protected] ~]# grep -q 'root' /etc/passwd
[[email protected] ~]# echo $?
0
4、--color # 帶有顔色過濾
[[email protected] ~]# grep --color -no 'xiaoxu' /etc/passwd
25:xiaoxu
25:xiaoxu
預設做過别名
[[email protected] ~]# alias
alias grep='grep --color=auto'
5、-i #忽略大小寫
[[email protected] ~]# echo "XIAOXU" | grep -i xiaoxu
XIAOXU
6、-A\-B\-C
# 列印比對行及比對行的後2行
[[email protected] ~]# grep -A 2 'root' /etc/passwd
# 列印比對行及比對行的前2行
[[email protected] ~]# grep -B 2 'root' /etc/passwd
# 列印比對行及比對行的前後兩行都列印
[[email protected] ~]# grep -C 2 'root' /etc/passwd
7、-c # 将比對到的行數列印出來
[[email protected] ~]# grep -c 'root' /etc/passwd
2
8、-v # 反向查找[取反]
[[email protected] ~]# grep -v 'root' /etc/passwd 列印所有不比對此規則的行。
[[email protected] ~]# ps aux | grep nginx | grep -v grep
[[email protected] ~]# ps aux | grep [n]ginx
9、-w # 過濾單詞
[[email protected] ~]# netstat -an |grep -w 80
tcp6 0 0 :::80 :::* LISTEN
[[email protected] ~]# netstat -an |grep '\<80\>'
tcp6 0 0 :::80 :::* LISTEN
[[email protected] ~]# netstat -an |grep '\b80\b'
tcp6 0 0 :::80 :::* LISTEN
# 10、-rl
[[email protected] ~]# grep -rl 'root' /etc/ # 将/etc目錄下所有包含'root'内容的檔案都列出來
三 正規表達式
3.1 正規表達式介紹
正規表達式,又稱規則表達式**。**(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE),是計算機科學的一個概念。正規表達式由元字元組成,通常被用來檢索、替換那些符合某個模式(規則)的文本(許多程式設計語言都支援利用正規表達式進行字元串操作)。
元字元:是一類可以表達出超越其字面本身含義的特殊字元
shell元字元(也稱為通配符): 由shell解釋器來解析,如rm -rf *.pdf,元字元*Shell将其解析為任意多個字元
正規表達式元字元 : 由各種執行模式比對操作的程式來解析,比如vi、grep、sed、awk
例如:vim示例:
:1,$ s/tom/EGON/g # 如anatomy、tomatoes及tomorrow中的“tom”被替換了,而Tom确沒被替換
:1,$ s/\<[Tt]om\>/EGON/g
3.2 正規表達式元字元
3.2.1 基本正則元字元集
#元字元 #功能 #示例
^ 行首 ^love
$ 行尾 love$
. 除了換行符以外的任意單個字元 l..e
* 前導字元的零個或多個 ab*love
.* 所有字元 a.*love
[] 字元組内的任一字元 [lL]ove
[^] 對字元組内的每個字元取反(不比對字元組内的每個字元) [^a-z0-9]ove
^[^] 非字元組内的字元開頭的行
[a-z] 小寫字母
[A-Z] 大寫字母
[a-Z] 小寫和大寫字母
[0-9] 數字
\ 用來轉義元字元 love\.
\< 詞首定位符 單詞一般以空格或特殊字元做分隔、連續的字元組成 \<love
\> 詞尾定位符 love\>
\(..\) 比對稍後将要使用的字元的标簽 \(love\)able\1er
:1,$ s/\(192.168.11\).66/\1.50/g
x\{m\} 字元x重複出現m次 e\{3\}
x\{m,\} 字元x重複出現m次以上 e\{3,\}
x\{m,n\} 字元x重複出現m到n次 e\{3,6\}
示例
# 1、^ 行首
[[email protected] ~]# grep '^root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
# 2、$ 行尾
[[email protected] ~]# grep 'bash$' /etc/passwd
root:x:0:0:root:/root:/bin/bash
user1:x:1002:1003::/home/user1:/bin/bash
egon1:x:198:1005::/home/egon1:/bin/bash
gg:x:1004:1006::/home/gg:/bin/bash
egon:x:1005:1007::/home/egon:/bin/bash
tom:x:1006:1008::/home/tom:/bin/bash
# 3、. 除了換行符以外的任意單個字元
[[email protected] ~]# grep 'r..t' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
# 4、* 前導字元的零個或多個
[[email protected] ~]# cat a.txt
a
ab
abb
abbb
bbbbb
[[email protected] ~]# grep 'ab*' a.txt
a
ab
abb
abbb
# 5、.* 所有字元=貪婪
[[email protected] ~]# cat a.txt
a123+-*/c11113333c
a1c
a77Ac
a23333c
ac
111
222
333
[[email protected] ~]# grep 'a.*c' a.txt
a123+-*/c11113333c
a1c
a77Ac
a23333c
ac
# 5.1 .*?=》非貪婪,預設情況下,grep不支援非貪婪修飾符,但您可以使用grep -P來使用Perl文法來支援.*?
[[email protected] ~]# cat a.txt
<a href="http://www.baidu.com">"我他媽的是百度"</a>
<a href="http://www.sina.com.cn">"我特麼的是新浪"</a>
[[email protected] ~]# grep -o 'href=".*" target="_blank" rel="external nofollow" ' a.txt # 貪婪
href="http://www.baidu.com">"我他媽的是百度"
href="http://www.sina.com.cn">"我特麼的是新浪"
[[email protected] ~]# grep -oP 'href=".*?" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" ' a.txt # 非貪婪
href="http://www.baidu.com"
href="http://www.sina.com.cn"
[[email protected] ~]# grep -Po 'href=".*?" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" ' a.txt | cut -d= -f2
"http://www.baidu.com"
"http://www.sina.com.cn"
# 6、[] 字元組内的任一字元
# 7、[^] 對字元組内的每個字元取反(不比對字元組内的每個字元)
[[email protected] ~]# cat a.txt
a1c
a2c
a33c
aAc
aZc
[[email protected] ~]# grep 'a[0-9]c' a.txt
a1c
a2c
[[email protected]gon ~]# grep 'a[^0-9]c' a.txt
aAc
aZc
[[email protected] ~]#
[[email protected] ~]# grep 'a[0-9][0-9]c' a.txt
a33c
[[email protected] ~]#
# 8、^[^] 非字元組内的字元開頭的行
[[email protected] ~]# cat a.txt
a1c
a2c
a33c
aAc
aZc
[[email protected] ~]# grep '^[^0-9]..$' a.txt
a1c
a2c
aAc
aZc
[[email protected] ~]#
# 9、[a-z] 小寫字母
# 10、[A-Z] 大寫字母
# 11、[a-Z] 小寫和大寫字母
# 12、[0-9] 數字
# 13、\< 單詞頭 單詞一般以空格或特殊字元做分隔,連續的字元串被當做單詞
# 14、\> 單詞尾
[[email protected] ~]# netstat -an |grep -w 80
tcp6 0 0 :::80 :::* LISTEN
[[email protected] ~]# netstat -an |grep '\<80\>'
tcp6 0 0 :::80 :::* LISTEN
[[email protected] ~]# netstat -an |grep '\b80\b'
tcp6 0 0 :::80 :::* LISTEN
Ps: grep比對換行符和制表符
[[email protected] ~]# echo -e "a\nb" |grep $'a\nb'
a
b
[[email protected] ~]#
[[email protected] ~]# echo -e "a\tb" |grep $'a\tb'
a b
3.2.2 擴充正則元字元集
# 擴充正則元字元
+ 比對一個或多個前導字元 [a-z]+ove
? 比對零個或一個前導字元 lo?ve
a|b 比對a或b love|hate
() 組字元 love(able|rs) (egon)+
(..)(..)\1\2 标簽比對字元 (love)able\1er
x{n} x出現n次 e{3}
x{n,} x出現n次至無窮次 e{3,}
x{n,m} x出現n次至m次 e{3,6}
# 若想使用擴充正則
grep加-E 或 egrep 或轉義\
sed 加 -r 參數 或轉義
AWK 直接支援大多數擴充正則,更多支援需要加選項--posix選項
示例
# ======================grep擴充正則示例======================
[[email protected] ~]# cat a.txt
a
ab
abb
abbb
abbbb
abbbbb
bbbbbbb
[[email protected] ~]# grep 'ab{2,4}' a.txt # 預設不支援擴充正則,是以沒效果
[[email protected] ~]# egrep 'ab{2,4}' a.txt
abb
abbb
abbbb
abbbbb
[[email protected] ~]#
# ======================sed擴充正則示例======================
[[email protected] ~]# sed -n '/roo?/p' /etc/passwd # 預設不支援擴充正則?
[[email protected] ~]# sed -n '/roo\?/p' /etc/passwd # 可以用\轉義擴充正則符号?
有結果,結果略...
[[email protected] ~]# sed -rn '/roo?/p' /etc/passwd # 也可以加-r選項
有結果,結果略...
[[email protected] ~]#
# ======================awk擴充正則示例======================
[[email protected] ~]# cat a.txt
a
ab
abb
abbb
abbbb
abbbbb
bbbbbbb
[[email protected] ~]# awk '/ab{1,3}/{print}' a.txt
ab
abb
abbb
abbbb
abbbbb
[[email protected] ~]# awk --posix '/ab{1,3}/{print}' a.txt
ab
abb
abbb
abbbb
abbbbb
總結
grep: 使用基本元字元集 ^, $, ., *, [], [^], \< \>,\(\),\{\}
egrep(或grep -E): 使用擴充元字元集 ?, +, { }, |, ( )
# 注:grep也可以使用擴充集中的元字元,僅需要對這些元字元前置一個反斜線
\w 所有字母與數字,稱為字元[a-zA-Z0-9] 'l[a-zA-Z0-9]*ve' 'l\w*ve'
\W 所有字母與數字之外的字元,稱為非字元 'love[^a-zA-Z0-9]+' 'love\W+'
\b 詞邊界 '\blove\b' '\<love\>'
3.2.3 posix定義的字元分類
# 表達式 功能 示例
[:alnum:] 字母與數字字元 [[:alnum:]]+
[:alpha:] 字母字元(包括大小寫字母) [[:alpha:]]{4}
[:blank:] 空格與制表符 [[:blank:]]*
[:digit:] 數字字母 [[:digit:]]?
[:lower:] 小寫字母 [[:lower:]]{5,}
[:upper:] 大寫字母 [[:upper:]]+
[:punct:] 标點符号 [[:punct:]]
[:space:] 包括換行符,回車等在内的所有空白[[:space:]]+
# 詳解
[:alnum:] Alphanumeric characters.
比對範圍為 [a-zA-Z0-9]
[:alpha:] Alphabetic characters.
比對範圍為 [a-zA-Z]
[:blank:] Space or tab characters.
比對範圍為 空格和TAB鍵
[:cntrl:] Control characters.
比對控制鍵 例如 ^M 要按 ctrl+v 再按回車 才能輸出
[:digit:] Numeric characters.
比對所有數字 [0-9]
[:graph:] Characters that are both printable and visible. (A space is print-
able, but not visible, while an a is both.)
比對所有可見字元 但不包含空格和TAB 就是你在文本文檔中按鍵盤上能用眼睛觀察到的所有符号
[:lower:] Lower-case alphabetic characters.
小寫 [a-z]
[:print:] Printable characters (characters that are not control characters.)
比對所有可見字元 包括空格和TAB
能列印到紙上的所有符号
[:punct:] Punctuation characters (characters that are not letter, digits, con-
trol characters, or space characters).
特殊輸入符号 +-=)(*&^%$#@!~`|\"'{}[]:;?/>.<,
注意它不包含空格和TAB
這個集合不等于^[a-zA-Z0-9]
[:space:] Space characters (such as space, tab, and formfeed, to name a few).
[:upper:] Upper-case alphabetic characters.
大寫 [A-Z]
[:xdigit:] Characters that are hexadecimal digits.
16進制數 [0-f]
# 使用方法:
[[email protected] ~]# grep --color '[[:alnum:]]' /etc/passwd
四 練習
正規表達式及字元處理
目标檔案/etc/passwd,使用grep指令或egrep
1.顯示出所有含有root的行:
2.輸出任何包含bash的所有行,還要輸出緊接着這行的上下各兩行的内容:
3. 顯示出有多少行含有nologin。
4.顯示出那些行含有root,并将行号一塊輸出。
5.顯示出檔案中
6.建立使用者
abominable
abominate
anomie
atomize
編寫正規表達式,将他們比對出來
egrep 'a.omi(nabl|nat|z|)e' /etc/passwd
7.建四個使用者
Alex213sb
Wpq2222b
yH438PIG
egon666
egon
過濾出使用者名組成是字母+數字+字母的行
[[email protected]-R3-srv ~]# egrep '^[a-Z]+[0-9]+[a-Z]+' /etc/passwd
8.顯示出/etc目錄下所有包含root的檔案名
9. 過濾掉/etc/ssh/sshd_config内所有注釋和所有空行
grep -v '^#' /etc/ssh/sshd_config |grep -v '^ *$'