一、Linux文本處理三劍客
Linux上有三種常用的文本處理工具,分別為:grep(egrep、fgrep)、sed、awk。今天主要給大家介紹一下三劍客中的第一劍:grep伐木累。
二、grep是什么?
grep 全稱(Globally search a Regular Expression and Print)是一個文本搜索工具,基于“pattern”(這里指的是過濾模式,多指正則表達式)對給定的文本進行搜索。
grep家族:
grep:支持使用基本正則表達式;
egrep:支持使用擴展正則表達式;
fgrep:不支持使用正則表達式;
# 雖然正則表達式有強大的引擎,但是在單獨過濾字符上面 fgrep要起到很大作用,這個作用在日志文件小的時候可能體現不出來,但是當文件達到幾億行就能體現出fgrep的搜索效率。(對大型web網站一天的日志量到幾億行是很輕松的,甚至更多)
三、grep與egrep的主要參數
在介紹正則表達式前,先介紹一下grep的常用參數,這里所有涉及正則表達式meta字符都會在后續中展開!
常用選項:
–color=auto:對匹配到的文本著色后高亮顯示;(默認centos7對grep、egrep、fgrep已經設置參數,此處不做過多例子)
# alias alias cp='cp -i' alias egrep='egrep --color=auto' alias fgrep='fgrep --color=auto' alias grep='grep --color=auto' alias l.='ls -d .* --color=auto' alias ll='ls -l --color=auto' alias ls='ls --color=auto' alias mv='mv -i' alias rm='rm -i' alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
-i:忽略字符大小寫;
# cat test Hello World How are you? Mageedu is very good! # grep "^H" test Hello World How are you? # grep "^h" test # grep -i "^h" test Hello World How are you?
-o:僅顯示匹配 到的文本自身;
# grep "good" test Mageedu is very good! [root@localhost ~]# grep -o "good" test good
-v,反向匹配;
# cat test Hello World How are you? Mageedu is very good! [root@localhost ~]# grep "M.*[[:punct:]]$" test Mageedu is very good! [root@localhost ~]# grep -v "M.*[[:punct:]]$" test Hello World How are you?
-q, 靜默模式,不輸出任何信息;(省得把輸出放到/dev/null,節省系統資源)
此處只是為了得到一個返回狀態
# grep -q "good" test # echo $? 0 # grep -q "goodddddddd" test # echo $? 1
-P, 支持使用pcre正則表達式(per語言);
-e PATTERN可以同時匹配多個模式;
# cat test Hello World How are you? Mageedu is very good! [root@localhost ~]# grep -e "good" -e "you" test How are you? Mageedu is very good!
-f FILEFILE為每行包含了一個pattern的文本文件,即grep script;(讀取文件中的每一行pattern來對指定FILE進行過濾)
-f與-e類似,都是匹配多個模式,只是-f選項讀取的是文本文件中的模式,逐行匹配。
-A NUM 顯示匹配出的后#行
-B NUM 顯示匹配出的前#行
-C NUM顯示匹配出的前后#行
# cat test Hello World How are you? Mageedu is very good! # grep -A 1 "you" test How are you? Mageedu is very good! # grep -B 1 "you" test Hello World How are you? # grep -C 1 "you" test Hello World How are you? Mageedu is very good!
下面參數針對grep命令而言:
-E:支持擴展的正則表達式相當與egrep;
-F, –fixed-strings:支持使用固定字符串,不支持正則表達式,相當于fgrep;
四、grep使用及正則表達式
1.正則表達式的組成
a、一般字符:沒有特殊意義的字符
b、特殊字符(meta字符):元字符,有在正則表達式中有特殊意義
2.下面講下正則表達式中常見的meta字符(元字符)
a、基本正則表達式meta字符
(1)字符匹配
.:匹配任意單個字符;
# 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
[ ]:匹配方位內的任意單個數字;
# fdisk -l |grep "[sh]d[a-z]\>" Disk /dev/sda: 128.8 GB, 128849018880 bytes, 251658240 sectors
[^]匹配范圍外的任意單個數字:托字符指取反之意,下面會講到
# cat test Hello World how are you? Mageedu is very good! # grep "^[^[:upper:]]" test how are you?
[[:upper:]]:所有大寫字母;
[[:lower:]]:所有小寫字母;
[[:digit:]]:所有的數字;
[[:alpha:]]:所有字母;
[[:alnum:]]:所有字母和數字;
[[:space:]]:空白字符;
[[:punct:]]:標點符號;
# cat test Hello World how are you? Mageedu is very good! # grep "[[:upper:]][[:lower:]].*[[:space:]]" test Hello World Mageedu is very good!
(2)匹配次數
主要用于限制字符要出現的次數,一般放在出現的次數的字符后面。
*:匹配前面的字符任意次(0,1或多次);
此處*表示前面的字符可以出現也可以不出現,所以將文件中所有的行都匹配出來了
# grep "a*" test1 ab aaaabcd bcd cd axxxxxxxd
.*:任意長度的任意字符(.為匹配單個字符,*為任意次)
此處.表示匹配任意單個字符,所以在過濾時,文件中的a必須出現至少一次
# grep "a.*" test1 ab aaaabcd axxxxxxxd cccabbbd
\+:匹配前面的字符至少1次;
# grep "a\+" test1 ab aaaabcd axxxxxxxd cccabbbd
\?:匹配前面的0次或1次,即前面的字符可有可無;
# grep "a\?" test1 ab aaaabcd bcd cd axxxxxxxd cccabbbd
\{\m}:固定匹配前面的字符出現m次,m為非負數;
# grep "a\{2\}" test1 aaaabcd aaxxxxxxxd cccaabbbd
\{m,n\}:至少出現m次,至多出現n次;
# grep "a\{1,3\}" test1 ab aaaabcd aaxxxxxxxd cccaabbbd
\{0,n\}:至多n次;
\{m,\}:至少m次;
(3)位置錨定
限制使用模式搜索文本,限制模式所匹配到的文本只能出現于目標文本的哪個位置;
^:行首錨定;用于模式的最左側,^PATTERN
$:行尾錨定;用于模式的最右側,PATTERN$
# ps -ef|grep "^root.*bash$" root 1143 1141 0 09:20 pts/0 00:00:00 -bash
^PATTERN$:要讓PATTERN完全匹配一整行;
# grep "^hello" /tmp/fstab hello hello world # grep "^hello$" /tmp/fstab hello
^$:空行;
常用語在文檔中過濾多余的空行,-v指取反之意
# cat test Hello World how are you? Mageedu is very good! # grep -v "^$" test Hello World how are you? Mageedu is very good!
^[[:space:]]*$:用來在^$匹配不到的時候使用;
此處指有的時候空行中包含空白字符,比如空格、制表符等,用^$就過濾不出來了,此處可以使用此命令過濾
# grep -v "^$" test Hello World how are you? Mageedu is very good! # grep -v "^[[:space:]]*$" test Hello World how are you? Mageedu is very good!
\<或\b:詞首錨定,用于單詞模式的左側,格式為\<PATTERN, \bPATTERN
# fdisk -l|grep "/dev/[sh]d[a-z]" Disk /dev/sda: 128.8 GB, 128849018880 bytes, 251658240 sectors /dev/sda1 * 2048 1026047 512000 83 Linux /dev/sda2 1026048 84912127 41943040 83 Linux /dev/sda3 84912128 126855167 20971520 83 Linux /dev/sda4 126855168 251658239 62401536 5 Extended /dev/sda5 126859264 131055615 2098176 82 Linux swap / Solaris # fdisk -l|grep "/dev/[sh]d[a-z]\>" Disk /dev/sda: 128.8 GB, 128849018880 bytes, 251658240 sectors
\>或\b:詞尾錨定,用于單詞模式的右側,格式為PATTERN\>, PATTERN\b
# grep "\<root" /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin
\<PATTERN\>:單詞錨定
單詞:由非特殊字符組成的連續字符(字符串)都稱為單詞;
# cat /tmp/ifconfig.test /usr/sbin/ifconfig /usr/sbin/ifconfig2 /usr/sbin/ifconfig3 # grep "ifconfig" /tmp/ifconfig.test /usr/sbin/ifconfig /usr/sbin/ifconfig2 /usr/sbin/ifconfig3 # grep "\<ifconfig\>" /tmp/ifconfig.test /usr/sbin/ifconfig
(4)分組與引用
\(PATTERN\):將次PATTERN匹配到的字符當做一個整體處理;分組括號中的模式匹配到的字符會被正則表達式引擎自動紀錄于變量中,這些變量分別是\1,\2,\3
\1:第一組括號中的pattern匹配到的字符串;
\2:第二組括號中的pattern匹配到的字符串;
# grep "^\([[:alnum:]]\+\)\>.*\1$" /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt nologin:x:5010:5010::/home/nologin:/sbin/nologin
b、擴展正則表達式meta字符
注意:與基本正則表達式不同,擴展表達式在一些參數上可以不使用轉意符(\),但是在使用上沒有什么區別,這里我舉幾個例子,其他基本與基本正則表達式使用相同!
此處表示過濾1-255的所有整數
此處表示取出絕對路徑中的基名
# echo `which pwd`|egrep "[^/]+/?$" /usr/bin/pwd # echo `which pwd`|egrep "[^/]+/?$" -o pwd
此處表示查看root、mageedu、centos用戶的詳細信息
# egrep "^(root|mageedu|centos)\>" /etc/passwd root:x:0:0:root:/root:/bin/bash mageedu:x:1000:1000:mageedu:/home/mageedu:/bin/bash centos:x:5008:5008::/home/centos:/bin/bash
(1)字符匹配
.:匹配任意單個字符;
[ ]:匹配方位內的任意單個數字;
[^]匹配范圍外的任意單個數字;
[[:upper:]]:所有大寫字母;
[[:lower:]]:所有小寫字母;
[[:digit:]]:所有的數字;
[[:alpha:]]:所有字母;
[[:alnum:]]:所有字母和數字;
[[:space:]]:空白字符;
[[:punct:]]:標點符號;
(2)匹配次數
主要用于限制字符要出現的次數,一般放在出現的次數的字符后面。
*:匹配前面的字符任意次(0,1或多次);
.*:任意長度的任意字符(.為匹配單個字符,*為任意次)
+:匹配前面的字符至少1次;
?:匹配前面的0次或1次,即前面的字符可有可無;
{m}:固定匹配前面的字符出現m次,m為非負數;
{m,n}:至少出現m次,至多出現n次;
{0,n}:至多n次;
{m,}:至少m次;
(3)位置錨定
擴展正則表達式中:單詞錨定符(\<,\>)不能去除轉意符(\)
^:行首錨定;用于模式的最左側,^PATTERN
$:行尾錨定;用于模式的最右側,PATTERN$
^PATTERN$:要讓PATTERN完全匹配一整行;
^$:空行;
^[[:space:]]*$:用來在^$匹配不到的時候使用;
\<或\b:詞首錨定,用于單詞模式的左側,格式為\<PATTERN, \bPATTERN
\>或\b:詞尾錨定,用于單詞模式的右側,格式為PATTERN\>, PATTERN\b
\<PATTERN\>:單詞錨定
單詞:由非特殊字符組成的連續字符(字符串)都稱為單詞;
(4)分組與引用
(PATTERN):將次PATTERN匹配到的字符當做一個整體處理;分組括號中的模式匹配到的字符會被正則表達式引擎自動紀錄于變量中,這些變量分別是\1,\2,\3
\1:第一組括號中的pattern匹配到的字符串;
\2:第二組括號中的pattern匹配到的字符串
這里的\1 \2不能省略轉意符;
(5)或者
a|b:a或者b
C|cat:表示C或cat
(C|c)at:表示Cat或cat
# fdisk -l|grep -E "/dev/(s|h)d[a-z]\>" Disk /dev/sda: 128.8 GB, 128849018880 bytes, 251658240 sectors
原創文章,作者:Ace,如若轉載,請注明出處:http://www.www58058.com/12494
很贊,已置頂