文本處理(grep與正則表達式)

首先先介紹一下這兩個命令:

正則表達式(Regular Expression),計算機科學的一個概念。正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規則的字符串。在很多文本編輯器裏,正則表達式通常被用來檢索、替換那些匹配某個模式的文本。

grep指令用於查找內容包含指定的範本樣式的文件,如果發現某文件的內容符合所指定的範本樣式,預設grep指令會把含有範本樣式的那一列顯示出來。若不指定任何文件名稱,或是所給予的文件名爲"-",則grep指令會從標準輸入設備讀取數據。

然後我們就開始實驗吧,後面再列出正則表達式的規則和grep的使用:

使用grep 進行搜索特定文本行
gec@ubuntu:~$ echo -e "what is your name?" | grep name
what is your name?

在文件中匹配特定的文本行,-n可以打印行號
gec@ubuntu:~$ cat -n test.txt 
     1	what is your name?
     2	my name is arron.
     3	and you?
     4	i am kobe.
     5	nice to meet you.
     6	nice to meet you.

gec@ubuntu:~$ grep name test.txt  -n
1:what is your name?
2:my name is arron.

匹配多個特定的文本行
gec@ubuntu:~$ cat test1.txt 
who am i?
maybe i am a smart boy.
i thank yes,i am right.
what is my name?

gec@ubuntu:~$ grep name test.txt  test1.txt 
test.txt:what is your name?
test.txt:my name is arron.
test1.txt:what is my name?
gec@ubuntu:~$ cat digit.txt 
1234567890
1122233334444556566677778889990000
aaaabbbbcccccddddddeeee
ansadasdkk
dashdk
foorjn

egrep 與 grep -e 是一樣的,使用正則表達式
gec@ubuntu:~$ egrep "[a-z]" digit.txt 
aaaabbbbcccccddddddeeee
ansadasdkk
dashdk
foorjn

gec@ubuntu:~$ grep -E "[a-z]" digit.txt 
aaaabbbbcccccddddddeeee
ansadasdkk
dashdk
foorjn

同樣也是可以反過來輸出
gec@ubuntu:~$ grep -E "[a-z]" digit.txt -v
1234567890
1122233334444556566677778889990000

使用-c 就是統計匹配到的行數
gec@ubuntu:~$ grep -E "[a-z]" digit.txt  -c
4

統計匹配的次數
gec@ubuntu:~$ grep -E "[a-z]" digit.txt -o | wc -l
45

列出字符串所在文件,-L是反向,不列出
gec@ubuntu:~$ grep name test.txt  test1.txt -l
test.txt
test1.txt
指定目錄遞歸搜索 --exclude排除  --include指定 --exclude-dir 排除目錄
grep "abcdefg" /home/gec -R

忽略大小寫
gec@ubuntu:~$ echo "AaBb" | grep "a" 
AaBb
gec@ubuntu:~$ echo "AaBb" | grep "a" -i
AaBb

多個模式匹配
gec@ubuntu:~$ echo "AaBb" | grep -e "a" -i -e "b"
AaBb

多個模式定義在文件裏
gec@ubuntu:~$ echo a b c > file.txt
gec@ubuntu:~$ cat file.txt 
a b c
gec@ubuntu:~$ echo a b c | grep -f file.txt 
a b c

-q是靜默輸出,我並不想看到你

-A打印前幾行,-B打印後幾行 -C打印前後幾行
gec@ubuntu:~/grep_t$ grep 5 -A 3 test2.txt 
5
6
7
8
gec@ubuntu:~/grep_t$ grep 5 -B 3 test2.txt 
2
3
4
5
gec@ubuntu:~/grep_t$ grep 5 -C 3 test2.txt 
2
3
4
5
6
7
8


把ip篩選出來

gec@ubuntu:~/grep_t$ cat ip.txt 
ens33     Link encap:Ethernet  HWaddr 00:0c:29:44:e5:13  
          inet addr:192.168.88.129  Bcast:192.168.88.255  Mask:255.255.255.0
          inet6 addr: fe80::10a5:3b92:2adc:12dd/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:272347 errors:0 dropped:0 overruns:0 frame:0
          TX packets:53869 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:147226936 (147.2 MB)  TX bytes:4381782 (4.3 MB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:9415 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9415 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:718609 (718.6 KB)  TX bytes:718609 (718.6 KB)

gec@ubuntu:~/grep_t$ grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" ip.txt 
          inet addr:192.168.88.129  Bcast:192.168.88.255  Mask:255.255.255.0
          inet addr:127.0.0.1  Mask:255.0.0.0

grep:

語法

grep [-abcEFGhHilLnqrsvVwxy][-A<顯示列數>][-B<顯示列數>][-C<顯示列數>][-d<進行動作>][-e<範本樣式>][-f<範本文件>][--help][範本樣式][文件或目錄...]

參數

  • -a 或 --text : 不要忽略二進制的數據。
  • -A<顯示行數> 或 --after-context=<顯示行數> : 除了顯示符合範本樣式的那一列之外,並顯示該行之後的內容。
  • -b 或 --byte-offset : 在顯示符合樣式的那一行之前,標示出該行第一個字符的編號。
  • -B<顯示行數> 或 --before-context=<顯示行數> : 除了顯示符合樣式的那一行之外,並顯示該行之前的內容。
  • -c 或 --count : 計算符合樣式的列數。
  • -C<顯示行數> 或 --context=<顯示行數>或-<顯示行數> : 除了顯示符合樣式的那一行之外,並顯示該行之前後的內容。
  • -d <動作> 或 --directories=<動作> : 當指定要查找的是目錄而非文件時,必須使用這項參數,否則grep指令將回報信息並停止動作。
  • -e<範本樣式> 或 --regexp=<範本樣式> : 指定字符串做爲查找文件內容的樣式。
  • -E 或 --extended-regexp : 將樣式爲延伸的普通表示法來使用。
  • -f<規則文件> 或 --file=<規則文件> : 指定規則文件,其內容含有一個或多個規則樣式,讓grep查找符合規則條件的文件內容,格式爲每行一個規則樣式。
  • -F 或 --fixed-regexp : 將樣式視爲固定字符串的列表。
  • -G 或 --basic-regexp : 將樣式視爲普通的表示法來使用。
  • -h 或 --no-filename : 在顯示符合樣式的那一行之前,不標示該行所屬的文件名稱。
  • -H 或 --with-filename : 在顯示符合樣式的那一行之前,表示該行所屬的文件名稱。
  • -i 或 --ignore-case : 忽略字符大小寫的差別。
  • -l 或 --file-with-matches : 列出文件內容符合指定的樣式的文件名稱。
  • -L 或 --files-without-match : 列出文件內容不符合指定的樣式的文件名稱。
  • -n 或 --line-number : 在顯示符合樣式的那一行之前,標示出該行的列數編號。
  • -o 或 --only-matching : 只顯示匹配PATTERN 部分。
  • -q 或 --quiet或--silent : 不顯示任何信息。
  • -r 或 --recursive : 此參數的效果和指定"-d recurse"參數相同。
  • -s 或 --no-messages : 不顯示錯誤信息。
  • -v 或 --revert-match : 顯示不包含匹配文本的所有行。
  • -V 或 --version : 顯示版本信息。
  • -w 或 --word-regexp : 只顯示全字符合的列。
  • -x --line-regexp : 只顯示全列符合的列。
  • -y : 此參數的效果和指定"-i"參數相同。

 

正則表達式:

普通字符

普通字符包括沒有顯式指定爲元字符的所有可打印和不可打印字符。這包括所有大寫和小寫字母、所有數字、所有標點符號和一些其他符號。


非打印字符

非打印字符也可以是正則表達式的組成部分。下表列出了表示非打印字符的轉義序列:

字符 描述
\cx 匹配由x指明的控制字符。例如, \cM 匹配一個 Control-M 或回車符。x 的值必須爲 A-Z 或 a-z 之一。否則,將 c 視爲一個原義的 'c' 字符。
\f 匹配一個換頁符。等價於 \x0c 和 \cL。
\n 匹配一個換行符。等價於 \x0a 和 \cJ。
\r 匹配一個回車符。等價於 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。注意 Unicode 正則表達式會匹配全角空格符。
\S 匹配任何非空白字符。等價於 [^ \f\n\r\t\v]。
\t 匹配一個製表符。等價於 \x09 和 \cI。
\v 匹配一個垂直製表符。等價於 \x0b 和 \cK。

特殊字符

所謂特殊字符,就是一些有特殊含義的字符,如上面說的 runoo*b 中的 *,簡單的說就是表示任何字符串的意思。如果要查找字符串中的 * 符號,則需要對 * 進行轉義,即在其前加一個 \: runo\*ob 匹配 runo*ob。

許多元字符要求在試圖匹配它們時特別對待。若要匹配這些特殊字符,必須首先使字符"轉義",即,將反斜槓字符\ 放在它們前面。下表列出了正則表達式中的特殊字符:

特別字符 描述
$ 匹配輸入字符串的結尾位置。如果設置了 RegExp 對象的 Multiline 屬性,則 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,請使用 \$。
( ) 標記一個子表達式的開始和結束位置。子表達式可以獲取供以後使用。要匹配這些字符,請使用 \( 和 \)。
* 匹配前面的子表達式零次或多次。要匹配 * 字符,請使用 \*。
+ 匹配前面的子表達式一次或多次。要匹配 + 字符,請使用 \+。
. 匹配除換行符 \n 之外的任何單字符。要匹配 . ,請使用 \. 。
[ 標記一箇中括號表達式的開始。要匹配 [,請使用 \[。
? 匹配前面的子表達式零次或一次,或指明一個非貪婪限定符。要匹配 ? 字符,請使用 \?。
\ 將下一個字符標記爲或特殊字符、或原義字符、或向後引用、或八進制轉義符。例如, 'n' 匹配字符 'n'。'\n' 匹配換行符。序列 '\\' 匹配 "\",而 '\(' 則匹配 "("。
^ 匹配輸入字符串的開始位置,除非在方括號表達式中使用,此時它表示不接受該字符集合。要匹配 ^ 字符本身,請使用 \^。
{ 標記限定符表達式的開始。要匹配 {,請使用 \{。
| 指明兩項之間的一個選擇。要匹配 |,請使用 \|。

限定符

限定符用來指定正則表達式的一個給定組件必須要出現多少次才能滿足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6種。

正則表達式的限定符有:

字符 描述
* 匹配前面的子表達式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等價於{0,}。
+ 匹配前面的子表達式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價於 {1,}。
? 匹配前面的子表達式零次或一次。例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等價於 {0,1}。
{n} n 是一個非負整數。匹配確定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的兩個 o。
{n,} n 是一個非負整數。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等價於 'o+'。'o{0,}' 則等價於 'o*'。
{n,m} m 和 n 均爲非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 將匹配 "fooooood" 中的前三個 o。'o{0,1}' 等價於 'o?'。請注意在逗號和兩個數之間不能有空格。

 

定位符

定位符使您能夠將正則表達式固定到行首或行尾。它們還使您能夠創建這樣的正則表達式,這些正則表達式出現在一個單詞內、在一個單詞的開頭或者一個單詞的結尾。

定位符用來描述字符串或單詞的邊界,^ 和 $ 分別指字符串的開始與結束,\b 描述單詞的前或後邊界,\B 表示非單詞邊界。

正則表達式的定位符有:

字符 描述
^ 匹配輸入字符串開始的位置。如果設置了 RegExp 對象的 Multiline 屬性,^ 還會與 \n 或 \r 之後的位置匹配。
$ 匹配輸入字符串結尾的位置。如果設置了 RegExp 對象的 Multiline 屬性,$ 還會與 \n 或 \r 之前的位置匹配。
\b 匹配一個單詞邊界,即字與空格間的位置。
\B 非單詞邊界匹配。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章