1. 程式人生 > >01-shell文字處理三劍客之grep

01-shell文字處理三劍客之grep

開篇:哈嘍,今天我想寫寫shell程式設計,打算平均一天一篇吧,這樣一個月後就可以進步比較多。
先從shell文字處理三劍客grep、sed、awk開始。聽說啊,要是我不會這個命令,就不好意思說自己會shell程式設計。

1 grep是什麼意思?

grep: Global search REgular expression and Print out the line.
文字搜尋工具,根據使用者指定的“模式(pattern)”對目標文字進行過濾,顯示被模式匹配到的行。
嘿嘿,我覺得學習grep,倒不如說是在學習模式匹配,也就是說正則表示式。
我們先來簡單實驗一下grep的用法:

[root@hadoop1 hadoop]# cat /etc/passwd
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
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin gopher:x:13:30:gopher:/var/gopher:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin dbus:x:81:81:System
message bus:/:/sbin/nologin usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin haldaemon:x:68:68:HAL daemon:/:/sbin/nologin gdm:x:42:42::/var/lib/gdm:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin apache:x:48:48:Apache:/var/www:/sbin/nologin saslauth:x:498:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin itcast01:x:500:500:itcast01:/home/itcast01:/bin/bash hadoop:x:501:501::/home/hadoop:/bin/bash mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash [root@hadoop1 hadoop]# cat /etc/passwd |grep root root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@hadoop1 hadoop]# cat /etc/passwd |grep --color root root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@hadoop1 hadoop]#

2 正則表示式
grep雖簡單,但是模式匹配不簡單呀,接下來學習的都是正則表示式。學正則表示式有什麼好處?其實我們做大資料的話,要進行資料清洗,或者爬蟲等等,都要用正則表示式,用處還是大大的。
正則表示式:由一類字元書寫的模式,其中有些字元不表示字元的字面意義,而是表示控制或通配的功能;
同一個元字元所表達的含義可以不一樣,依此分為兩類:基礎正則表示式和擴充套件正則表示式。一定要明確你所寫的是屬於基礎正則表示式還是擴充套件正則表示式。
寫模式匹配一定要加單引號’ ‘,比如grep –color ‘r..t’ /etc/passwd

[root@hadoop1 hadoop]# grep --color '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
[root@hadoop1 hadoop]# 

2.1 字元匹配
.:匹配任意單個字元
[]:匹配指定集合中的任意單個字元
[[:digit:]], [0-9]
[[:lower:]], [a-z]
[[:upper:]], [A-Z]
[[:alpha:]], [a-zA-Z]
[[:alnum:]], [0-9a-zA-Z]
[[:space:]]
[[:punct:]]

[[email protected] shelltest]# grep --color 'abcdef[[:digit:]][[:digit:]][0-9]' test
abcdef123
[[email protected] shelltest]# grep --color 'abcdef[[:digit:]]' test
abcdef123
[[email protected] shelltest]# grep --color 'abc' test
abcdef123
[[email protected] shelltest]# grep -o --color 'abc' test
abc
[[email protected] shelltest]# 

[^]:匹配指定集合外的任意單個字元

[root@hadoop1 shelltest]# grep --color 'abcdef[^[:digit:]]' test
[root@hadoop1 shelltest]# 
[root@hadoop1 shelltest]# grep --color 'xielaoshi[^a-z]' test
xielaoshi121314
xiexiexielaoshi133
[root@hadoop1 shelltest]# 

2.2匹配次數:
用於對其前面緊鄰的字元所能夠出現的次數作出限定。語法如下
*: 匹配其前面的字元任意次,0,1或多次;
例如:grep ‘x*y’
xy, xxy, xxxy, y
\?:匹配其前面的字元0次或1次;
例如:grep ‘x\?y’
xy, xxy, y, xxxxxy, aby
+: 匹配其前面的字元出現至少1次;
{m}: 匹配其前面的字元m次;
例如:grep ‘x{2}y’
xy, xxy, y, xxxxxy, aby
{m,n}:匹配其前面的字元至少m次,至多n次;
例如: grep ‘x{2,4}y’
xy, xxy, y, xxxxxxy, aby
grep ‘x{0,4}y’
xy, xxy, y, xxxxxxxxxy, aby
grep ‘x{2,}y’
xy, xxy, y, xxxxxy
.*: 匹配任意長度的任意字元

實驗一下:

[root@hadoop1 shelltest]# vi test 
[root@hadoop1 shelltest]# cat test 
xielaoshi121314
xiexiexielaoshi133
xie123laoshi
xielaoshi
abcdef123

xy
xxy
xxxxy
y
aby
[root@hadoop1 shelltest]# grep --color 'x*y' test
xy
xxy
xxxxy
y
aby
[root@hadoop1 shelltest]# 
[root@hadoop1 shelltest]# grep --color 'x\+y' test
xy
xxy
xxxxy
[root@hadoop1 shelltest]# grep --color 'x\{2\}y' test
xxy
xxxxy
[root@hadoop1 shelltest]# grep --color 'x\{0,4\}y' test
xy
xxy
xxxxy
y
aby
[root@hadoop1 shelltest]# grep --color 'x\{2,\}y' test
xxy
xxxxy
[root@hadoop1 shelltest]# grep --color 'x.*i' test
xielaoshi121314
xiexiexielaoshi133
xie123laoshi
xielaoshi
[root@hadoop1 shelltest]# 

如果你跟著敲命令,會不會感覺“\”不知道啥意思?其實它就是轉義字元。

2.3 位置錨定:

^: 行首錨定
        寫在模式的最左側
$: 行尾錨定
        寫在模式的最右側
^$: 空白行
\<: 詞首錨定, \b
        出現在要查詢的單詞模式的左側;\<char
\>:詞尾錨定, \b
        出現在要查詢的單詞模式的右側;char\>
\<pattern\>: 匹配單詞
[root@hadoop1 shelltest]# grep --color '\<r' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
[root@hadoop1 shelltest]# grep --color '\<ha' /etc/passwd
halt:x:7:0:halt:/sbin:/sbin/halt
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
hadoop:x:501:501::/home/hadoop:/bin/bash
[root@hadoop1 shelltest]# grep --color 'tor\>' /etc/passwd
operator:x:11:0:operator:/root:/sbin/nologin
[root@hadoop1 shelltest]# grep --color '\<root\>' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@hadoop1 shelltest]# 

2.4 分組
()

後向引用:模式中,如果使用\(\)實現了分組,在某行文字的檢查中,如果\(\)的模式匹配到了某內容,此內容後面的模式中可以被引用;
    \1, \2, \3
模式自左而右,引用第#個左括號以及與其匹配右括號之間的模式匹配到的內容;
[root@hadoop1 shelltest]# cat test
xielaoshi121314
xiexiexielaoshi133
xie123laoshi
xielaoshi
abcdef123

xy
xxy
xxxxy
y
aby
abababy
by
bby
[root@hadoop1 shelltest
[root@hadoop1 shelltest]# grep --color 'ab*y' test
aby
abababy
[root@hadoop1 shelltest]# grep --color 'ab\{1\}y' test
aby
abababy
[root@hadoop1 shelltest]# vi test 
[root@hadoop1 shelltest]# grep --color 'ab\{1,\}' test
abcdef123
aby
abbbby
abababy
[root@hadoop1 shelltest]# grep --color '\(ab\)\{1,\}y' test
aby
abababy
[root@hadoop1 shelltest]# 

後向引用:

[[email protected] shelltest]# grep --color '\(ab\)\{1,\}y\1' test
abababyab

3 grep選項
-v: 反向選取
-o: 僅顯示匹配到內容
-i: 忽略字元大小寫
-E: 使用擴充套件正則表示式
-A #: 顯示匹配字元的下面的行數內容
-B #:顯示匹配字元的下面的行數內容
-C #:顯示匹配字元的上下面的行數內容

[root@hadoop1 shelltest]# grep -A 2 'abababyab' test
abababyab
by
bby
[root@hadoop1 shelltest]# grep -B 2 'abababyab' test
aby
abbbby
abababyab
[root@hadoop1 shelltest]# grep -C 2 'abababyab' test
aby
abbbby
abababyab
by
bby
[root@hadoop1 shelltest]# 

以上三個命令在查詢日誌的時候很有用。

4 egrep及擴充套件的正則表示式
擴充套件正則表示式的元字元:
字元匹配:
.
[]
[^]
匹配次數限定:
*
?: 匹配其前面字元0次或1次;
+:匹配其前面的字元至少1次;
{m}:匹配其前面的字元m次;
{m,n}:{m,}, {0,n}
錨定:
^
$
\<, >: \b
分組:
()

            支援後向引用:\1, \2, ...
        或者:
            a|b: a或者b
            ab|cd:

    # grep -E 'pattern' file...
    # egrep 'pattern' file...

其實擴充套件正則表示式相比較於基礎正則表示式,擴充套件正則表示式少了‘\’斜槓。

[root@hadoop1 shelltest]# grep --color 'xie[1x]' test
xiexiexielaoshi133
xie123laoshi
[root@hadoop1 shelltest]# egrep --color 'xie1|x' test
xielaoshi121314
xiexiexielaoshi133
xie123laoshi
xielaoshi
xy
xxy
xxxxy
[root@hadoop1 shelltest]# grep --color 'xie1\|x' test
xielaoshi121314
xiexiexielaoshi133
xie123laoshi
xielaoshi
xy
xxy
xxxxy
[root@hadoop1 shelltest]# grep -E --color 'xie1|x' test
xielaoshi121314
xiexiexielaoshi133
xie123laoshi
xielaoshi
xy
xxy
xxxxy
[root@hadoop1 shelltest]# grep --color 'xie\(1\|x\)' test
xiexiexielaoshi133
xie123laoshi
[root@hadoop1 shelltest]# 

好了,有點累了,今天就先玩到這裡吧。如果你看到此文,想進一步學習或者和我溝通,加我微信公眾號:名字:五十年後
see you again! !
這裡寫圖片描述