1. 程式人生 > >文本處理三劍客之 grep

文本處理三劍客之 grep

digi pro 文件路徑 his 1-1 基本 文本搜索工具 ... 大寫

grep簡介

grep(Global search REgular expression and Print out the line)是Linux上的文本處理三劍客之一,另外兩個是sed和awk.

grep是文本搜索工具,根據用戶指定的pattern(由文本字符及正則表達式元字符編寫的過濾條件)對目標文本逐行進行匹配檢查並打印出符合條件的行.

grep有三個版本:grep,egrep和fgrep. egrep是擴展的grep,等同於grep -E,fgrep是快速grep,不支持正則表達式.

之前覺得glob跟grep正則很相似,其實他們的區別還挺大:

glob匹配文件名,grep匹配文件內容

glob是全部匹配,grep是部分匹配

正則表達式(Regular Expression,在代碼中常簡寫為regex、regexp或RE):

正則表達式是對字符串(包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為“元字符”))操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個“規則字符串”,這個“規則字符串”用來表達對字符串的一種過濾邏輯。正則表達式是一種文本模式,模式描述在搜索文本時要匹配的一個或多個字符串。

不同版本的grep對正則表達式的支持有所不同:

grep:默認是使用基本正則表達式(BRE)

egrep:支持擴展的正則表達式(ERE)

fgrep:不支持正則表達式(但搜索速度快)

grep命令:

命令格式:

grep [OPTIONS] PATTERN [FILE...]

grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

常用選項:

--color=auto:對匹配到的文本著色高亮顯示

-i:忽略字符大小寫

-o:僅顯示匹配到的文本自身(默認顯示匹配到的文本整行)

-v,--invert-match:顯示不能被pattern匹配到的行

-E,--extened-regexp:支持擴展的正則表達式(ERE).相當於egrep命令

-F,--fixed-strings:相當於fgrep命令

-q,--quiet,--silent:靜默模式,不輸出任何信息,取命令退出狀態碼時常用

-G,--basic-regexp:支持使用基本正則表達式

-P,--perl-regexp:支持使用pcre正則表達式(支持元字符很多)

-e PATTERN,--regexp=PATTERN:使用多模式

-f FILE,--file=:FILE為每行包含了一個pattern的文本文件,即grep script,把模式寫在一個文件裏,通過讀取文件(腳本文件),來匹配

-c:顯示統計匹配到的行數

-r,--recursive:對目錄下所有文件裏的內容根據模式匹配

-A #,--after-context=#:表示顯示匹配到行的後面#行

-B #,--before-context=#:表示顯示匹配到行的前面#行

-C #,-#,--context=#:表示顯示匹配到行的前後#行

示例:

# grep ‘root‘ /etc/passwd:如果模式裏有變量要用雙引號

技術分享圖片

# grep -v ‘root‘ /etc/passwd:反向匹配,顯示所有沒有被匹配的行

技術分享圖片

# grep -i ‘bash‘ bash.txt:忽略字符大小寫

技術分享圖片

# grep -o ‘root‘ /etc/passwd:僅顯示匹配到的文本自身

技術分享圖片

# grep -q ‘root‘ /etc/passwd:靜默模式

技術分享圖片

示例:

# grep -e "r..t" -e "bash" /etc/passwd:使用多模式

技術分享圖片

# grep -f /root/test/mypat /etc/passwd:使用保存在文件裏的匹配模式,模式無需加引號.

技術分享圖片

# grep -A 1 "^[op]" /etc/passwd:顯示匹配到的行後面的一行

技術分享圖片

# grep -B 2 "^[op]" /etc/passwd:顯示匹配到的行前面的兩行

技術分享圖片

# grep -C 1 "^[op]" /etc/passwd:顯示匹配到的行前後各一行

技術分享圖片

基本正則表達式元字符:

1、字符匹配:

.:匹配任意單個字符

[]:匹配範圍內的任意單個字符

[^]:匹配範圍外的單個字符

[:digit:]:任意單個數字

[:lower:]:任意單個小寫字母

[:upper:]:任意單個大寫字符

[:alpha:]:任意單個字母

[:alnum:]:任意單個字母和數字

[:space:]:任意單個空白字符

[:blank:]:任意單個空格和tab

[:punct:]:任意單個標點符號

[:cntrl:]:任意單個控制符

[:graph:]:任意單個能顯示的符號

[:print:]:任意單個可打印符號

[:xdigit:]:任意單個十六進制字符

示例:

# ifconfig | grep "r..":r後跟兩個字符的行

技術分享圖片

# ifconfig | grep -i "i[a-z][a-z]":不區分大小寫,i後跟兩個字母的行

技術分享圖片

# ifconfig | grep "i[[:alpha:]][[:space:]]":i後跟一個字母再跟一個空格的行

技術分享圖片

2、次數匹配:

用在要指定其出現的次數的字符後面,用於限制其前面的字符要出現的次數,默認工作在貪婪模式

*:匹配前面的字符出現的任意次(0,1或多次)

grep "x*y":只要有y就匹配

技術分享圖片

.*:匹配任意長度的任意字符,相當於glob中的*

grep "x.*y":在x和y之間可出現任意長度任意字符即匹配

技術分享圖片

\+:匹配前面的字符至少1次(1次或多次);\為轉義符

grep "x\+y":y之前必須出現一個x

技術分享圖片

\?:匹配前面的字符0次或1次,即前面的字符可有可無

grep "x\?y":只要有y就匹配

技術分享圖片

\{m\}:匹配其前面的字符出現m次,m為非負整數

grep "x\{2\}y":y前出現2次x就匹配

技術分享圖片

\{m,n\}:匹配其前面的字符出現m次,m為非負整數;閉區間[m,n]

技術分享圖片

\{0,n\}:至多n次

技術分享圖片

因為會匹配多次,所以全部都會匹配

\{m,\}:至少m次

技術分享圖片

示例:

# ifconfig | grep "i[[:alpha:]]\{3\}":匹配i後跟3個字母的行

技術分享圖片

# ifconfig | grep "i[[:alpha:]]\{3,\}":匹配i後跟至少3個字母的行

技術分享圖片

3、位置錨定:

限制使用模式搜索文本,限制模式所匹配到的文本只能出現於目標文本的哪個位置

^:行首錨定;用於模式的最左側,^PATTERN

$:行尾錨定;用於模式的最右側,PATTERN$

^PATTERN$:要讓PATTERN完全匹配一整行

^$:匹配空行;

^[[:space:]].*$:匹配空白行;

示例:

# grep "^r..t" /etc/passwd:匹配r開頭後跟兩個字符再跟t的行

技術分享圖片

# grep "l.\{3\}n" /etc/passwd:匹配l後跟3個字符再跟n的行

技術分享圖片

# grep "l.\{3\}n$" /etc/passwd:匹配l後跟3個字符再跟n結尾的行

技術分享圖片

# grep "[[:space:]]\+" /etc/passwd:匹配至少連續出現一個空格的行

技術分享圖片

單詞:非特殊字符組成的連續字符(字符串)都稱為單詞

\<或\b:詞首錨定,用於單詞模式的左側,格式為\<PATTERN,/bPATTERN

\>或\b:詞尾錨定,用於的承諾模式的右側,格式為PATTERN\>,PATTERN\b

示例:

# grep "\<r..t" /etc/passwd:匹配單詞詞首:r後跟兩個字符再跟t的行

技術分享圖片

# grep "\<r..t\>" /etc/passwd:匹配單詞:r後跟兩個字符再跟t的行

技術分享圖片

# ifconfig | grep "\<[0-9]\{3\}\>":匹配單詞:三個數字

技術分享圖片

更多實例:

1、顯示/etc/passwd文件中不以bash結尾的行

# grep -v ‘bash$‘ /etc/passwd

技術分享圖片

2、找出/etc/passwd文件中的三位或四位數

# grep ‘\<[0-9]\{3,4\}\>‘ /etc/passwd

技術分享圖片

3、找出/etc/grub2.cfg文件中,以至少一個空白字符開頭,後面又跟了一非空白字符的行

# grep ‘^[[:space:]]\+[^[:space:]]‘ /etc/grub2.cfg

技術分享圖片

4、找出"netstat -tan"命令的結果中,以‘LISTEN’後跟0或多個空白字符結尾的行

# netstat -tan | grep ‘LISTEN[[:space:]]*$‘

技術分享圖片

5、找出“fdisk -l”命令結果中,以/dev/後跟sd或hd及一個小寫字母的行

# fdisk -l | grep ‘/dev/[sh]d[a-z]\>‘

技術分享圖片

6、找出“ldd /usr/bin/cat”命令的結果中的文件路徑

# ldd /usr/bin/cat | grep -o ‘/[^[:space:]]\+‘

技術分享圖片

4、分組與引用:

\(PATTERN\):將此PATTERN匹配到的字符當作一個不可分割的整體進行處理

註意:分組括號中的模式匹配到的字符會被正則表達式引擎自動記錄於內部變量中,這些變量是\1,\2,\3,...

例如:pat1\(pat2\)pat3\(pat4\(pat5)pat6\)

\n:模式中的第n個左括號以及與之匹配的右括號之間的模式所匹配到的字符串(不是模式,而是模式匹配的結果)

\1:表示第一組括號總的PATTERN匹配到的的字符串;上例:pat2

\2:表示第二組括號總的PATTERN匹配到的的字符串;上例:pat4\(pat5)pat6

\3:表示第三組括號總的PATTERN匹配到的的字符串;上例:pat5

...

示例,文檔test內容如下:

he love his lover

he like his lover

he love his liker

he like his liker

.*l..e.*l..er

\(l..e\).*\1r

# grep -o ‘l..e.*l..er‘ test:不能完成精確匹配

技術分享圖片

# grep -o ‘\(l..e\).*\1r‘ test:分組可完成精確匹配

技術分享圖片

後向引用:引用前面的括號中的模式所匹配到的字符串

egrep命令:

命令格式

egrep [OPTIONS] PATTERN [FILE...]

命令選項:

egrep的選項與grep相同

擴展正則表達式的元字符:無需轉義符

字符匹配:

.:匹配任意單個字符

[]:匹配範圍內的任意單個字符

[^]:匹配範圍外的單個字符

[:digit:]:任意單個數字

[:lower:]:任意單個小寫字母

[:upper:]:任意單個大寫字符

[:alpha:]:任意單個字母

[:alnum:]:任意單個字母和數字

[:space:]:任意單個空格

[:blank:]:任意單個空格和tab

[:punct:]:任意單個標點符號

次數匹配:

*:匹配前面的字符(可有可無)出現的任意次(0,1或多次)

?:匹配前面的字符0次或1次,即前面的字符可有可無

+:匹配前面的字符至少1次(1次或多次)

{m}:匹配其前面的字符出現m次,m為非負整數

{m,n}:匹配其前面的字符出現m次,m為非負整數

{0,n}:至多n次

{m,}:至少m次

位置錨定:

^:行首錨定;用於模式的最左側,^PATTERN

$:行尾錨定;用於模式的最右側,PATTERN$

^PATTERN$:要讓PATTERN完全匹配一整行

^$:匹配空行

\<,\b:詞首錨定,用於單詞模式的左側,格式為\<PATTERN,/bPATTERN

\>,\b:詞尾錨定,用於的承諾模式的右側,格式為PATTERN\>,PATTERN\b

分組及引用:

(pattern):分組,括號中的模式匹配到的字符會被存儲於正則表達式引擎內部的變量中

後向引用:\1,\2,\3,...

或者:

a|b:a或者b

C|cat:表示C或cat

(C|c)at:表示Cat或cat

egrep實例:

1、顯示/etc/passwd文件中不以bash結尾的行

# egrep -v ‘bash$‘ /etc/passwd

技術分享圖片

2、找出/etc/passwd文件中的三位或四位數

# egrep ‘\<[0-9]{3,4}\>‘ /etc/passwd

技術分享圖片

3、找出/etc/grub2.cfg文件中,以至少一個空白字符開頭,後面又跟了一非空白字符的行

# egrep ‘^[[:space:]]+[^[:space:]]‘ /etc/grub2.cfg

技術分享圖片

4、找出"netstat -tan"命令的結果中,以‘LISTEN’後跟0或多個空白字符結尾的行

# netstat -tan | egrep ‘LISTEN[[:space:]]*$‘

技術分享圖片

5、找出“fdisk -l”命令結果中,以/dev/後跟sd或hd及一個小寫字母的行

# fdisk -l | egrep ‘/dev/[sh]d[a-z]\>‘

# fdisk -l | egrep ‘/dev/(s|h)d[a-z]\>‘

技術分享圖片

6、找出“ldd /usr/bin/cat”命令的結果中的文件路徑

# ldd /usr/bin/cat | egrep -o ‘/[^[:space:]]+‘

技術分享圖片

7、找出/proc/meninfo文件中,所有以大寫或小寫s開頭的行,至少用三種方式實現

# egrep "^(s|S)" /proc/meminfo

# grep "^[sS]" /proc/meminfo

# grep -i "^s" /proc/meminfo

技術分享圖片

8、顯示當前系統上root,centos,或slackware用戶的相關信息

# egrep "^(root|centos|slackware)\>" /etc/passwd

# egrep "^(root|centos|slackware):" /etc/passwd

技術分享圖片

9、echo輸出一個絕對路徑,使用grep取出基名

# echo /etc/passwd/ | egrep -o "[^/]+/?$"

技術分享圖片

10、找出ifconfig命令結果中的1-255之間的整數

# ifconfig| egrep "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>"

技術分享圖片

11、添加用戶bash、testbash、及nologin,要求前三個用戶的默認shell為/bin/bash,而後找出其用戶名與shell相同的用戶

# egrep "^([a-z0-9]+)\>.*\1$" /etc/passwd

技術分享圖片

文本處理三劍客之 grep