1. 程式人生 > >Linux篇 | 文本處理工具和正則表達式(二)

Linux篇 | 文本處理工具和正則表達式(二)

選項 條件 直接 per 十六 你是 rap 基本正則表達式 watermark

文本處理工具和正則表達式

Linux文本處理三劍客

  1. grep:文本過濾(模式:pattern)工具
    >grep, egrep, fgrep(不支持正則表達式搜索)

  2. sed:stream editor,文本編輯工具
  3. awk:Linux上的實現gawk,文本報告生成器

本篇主要講述grep

一.grep

  • 作用:文本搜索工具,根據用戶指定的“模式”對目標文本逐行進行匹配檢
    查;打印匹配到的行。(模式就是“正則表達式”)
  • 模式:由正則表達式字符及文本字符所編寫的過濾條件

格式:grep [OPTIONS] PATTERN [FILE...]

  1. [OPTIONS]:

    >--color=auto: 對匹配到的文本著色顯示
    >-m # 匹配#次後停止
    >-v 顯示不被pattern匹配到的行
    >-I 忽略字符大小寫
    >-n 顯示匹配的行號
    >-c 統計匹配的行數
    >-o 僅顯示匹配到的字符串
    >-q 靜默模式,不輸出任何信息
    >-A # after, 後#行
    >-B # before, 前#行
    >-C # context, 前後各#行
    >-e 實現多個選項間的邏輯or關系
    >grep –e ‘cat ’ -e ‘dog’ file
    >-w 匹配整個單詞
    >-E 使用ERE
    >-F "grep -f"相當於fgrep命令,不支持正則表達式
    >-f file 根據模式文件處理,就是把過濾條件寫在文本裏,可以是很多條件

  2. PATTERN:(可以是字符也可以是正則表達式)

總結:

grep的工作方式是:逐行處理。grep有一個內存空間,假如有一個文件有六行,grep會先把文件的第一行放到內存空間進行處理,如果第一行有關鍵字就進行打印;接著把第二行放到內存空間處理,如果第二行沒有關鍵字,就不管它;接著把第三行放到內存空間處理,依次類推處理文本的每一行。

示例1:
註意""和‘‘和所表示的含義。即""表示特定符號,如變量;‘‘表示字符,不管你是不是特定符號,在‘‘裏面都將表示表面意思,即字符;

表示命令的結果,即``裏面可寫命令,最後表現的結果就是命令的結果。

grep root /etc/passwd(過濾/etc/passwd文件中帶root的行)
grep "$USER" /et/passwd(過濾/etc/passwd文件中帶USER變量的行)
grep ‘$USER‘ /etc/passwd(過濾/etc/passwd文件中帶$USER字符的行)
grep whoami /etc/passwd(過濾/etc/passwd文件中帶"whoami命令結果"的行)

示例2:挑選特定的行
挑選帶root的行,找到一行就結束

grep -m1 whoami /etc/passwd

示例3:顯示不被模式(PATTERN)匹配到的行
顯示不匹配root的行

grep -v root /etc/passwd

示例4:忽略大小寫
顯示root,root忽略大小寫

grep -i ROOT /etc/passwd

示例5:顯示行號
顯示匹配root的行並標明行號

grep -n root /etc/passwd

示例6:顯示匹配的行數
顯示匹配root的行數有幾行

grep -c root /etc/passwd

示例7:僅顯示匹配到的字符,並且每個字符為一行
僅顯示匹配的root

grep -o root /etc/passwd

示例8:找到找不到,模式對不對都不顯示

grep -q root /etc/passwd
執行完上面的命令後,上面的命令一般配合echo $?,如果結果為0便是“成功”;$?結果非0,表示“失敗”。

示例9:找到行的前幾行、後幾行、中間幾行
有時候我們要找的東西不是很容易找,但是它旁邊的行比較容易找,所以“-A”選項找到指定行的後#行(包括指定行);“-B” 選項找到指定行的前#行(包括指定行); “-C”選項找到指定行的前後#行(包括指定行)。

示例10:包含多個字符串的行
使用“-e”,或的意思。如下面例子,顯示/etc/passwd中root或wang的字符

grep -e root -e wang /etc/passwd
顯示/etc/passwd中root並且bash的字符
grep root /etc/passwd | grep bash

示例11:顯示匹配單詞的行
“-w”選項表示匹配單詞為什麽什麽的行(如root的行),如果不加“-w”顯示匹配什麽字符的行(如root的行也算,roother的行也算)。單詞的範圍是字母數字下劃線(如1root、2_root),如果標點符號就不是單詞(如“;root”和“;root-”,註意雙引號不能丟)。

grep -w root /etc/passwd

正則表達式

正則表達式是處理文件內容的,通配符是處理文件名的。如果用正則表達式處理文件名也行,就是把正則表達式當成字符串,如加“\”符號,所以沒人這麽用。

介紹:

  1. REGEXP:Regular Expressions(正則表達式),由一類特殊字符及文本字符所編寫的模式,其中有些字符(元字符)不表示字符字面意義,而表示控制或通配的功能,例如“通配符”。
  2. 支持:grep,sed,awk,vim, less,nginx,varnish等
  3. 分兩類,兩個只是寫法有點區別,實現功能都一樣:
    > 基本正則表達式:BRE(寫法:grep -E)
    > 擴展正則表達式:ERE(寫法:egrep)

  4. 正則表達式引擎:
    正則表達式由於要匹配字符,所以背後有一些算法來支撐處理這些字符的功能,在不同的算法中,PCRE(Perl Compatible Regular Expressions)是著名的檢查處理正則表達式算法的軟件模塊之一,PCRE是基於Perl語言實現的(老牌語言)。
  5. 表達正則表達式的元字符的分類:
    字符匹配、匹配次數、位置錨定、分組
  6. 正則表達式的幫助:man 7 regex

一.基本正則表達式元字符

1.字符匹配

. 匹配任意單個字符
[] 匹配指定範圍內的任意單個字符,示例:[wang]包含w,a,n,g字符的行
[^] 匹配指定範圍外的任意單個字符
[:alnum:] 字母和數字
[:alpha:] 代表任何英文大小寫字符,亦即 A-Z, a-z
[:lower:] 小寫字母 [:upper:] 大寫字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的範圍廣)
[:cntrl:] 不可打印的控制字符(退格、刪除、警鈴...)
[:digit:] 十進制數字 [:xdigit:]十六進制數字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 標點符號

示例:匹配/etc/passwd文件中大寫字母的行

grep ‘[[:upper:]]‘ /etc/passwd

2.匹配次數

用在要指定次數的字符後面,用於指定前面的字符要出現的次數

技術分享圖片

示例1:*的貪婪模式,有多少都要匹配
匹配a字符

echo aaabc | grep "a*"
aaabc(匹配成功)

註釋:下面的示例因為文本編輯器不支持“\"號,所以用圖片表示。

技術分享圖片

練習題:使用grep前面已知的知識,匹配出當前的IP地址
答案:

技術分享圖片

3.位置錨定

技術分享圖片

註意:[^#]是匹配不是#號開頭的一個字符的行;“^#”是匹配#號開頭且位於行首的行

示例1:行首錨定,用於模式的最左側
匹配root,位於行首的行

grep "^root" /etc/passwd

示例2:行尾錨定,用於模式的最右側
匹配以“bash”結尾的行

grep "bash$" /etc/passwd

示例3:匹配文本中的空行

grep "^$" /etc/fstab

示例4:匹配文本中的空白行

grep "^[[:space:]]*$"

示例5:匹配單詞詞首,匹配的字符位於模式的最左側(註意不是行的最左側)
匹配單詞root,位於詞首

grep " \ <root" /etc/passwd -->註意:反斜線和小於號之間沒有空格,因為文本編輯器的原因我只能加空格才能顯示。
或者
grep "\broot" /etc/passwd

示例6:匹配單詞詞尾,匹配的字符位於模式的最右側(註意不是行的最右側)
匹配單詞root,位於詞尾

grep "root\ >" /etc/passwd ->註意:反斜線和小於號之間沒有空格,因為文本編輯器的原因我只能加空格才能顯示。
或者
grep "root\b" /etc/passwd

示例7:匹配整個單詞
匹配單詞是root的行

grep "\ <root\ >" /etc/passwd -->註意反斜線和小於號之間沒有空格
或者
grep "\broot\b" /etc/passwd

4.正則表達式分組

技術分享圖片

示例1:匹配abc為整體的行

技術分享圖片

示例2:多次分組
顯示分組abcabcabc和xyz

技術分享圖片

示例3:多次分組和後續引用
顯示分組abcabcabc和xyz和abc
**註意:“\1”表示第一個分組中,最後匹配的最終結果,而不是單純的如示例中的abc;那麽“\2”就表示第二個分組中,最後匹配的最終結果。如果不明白請看示例4。

技術分享圖片

示例4:多次分組和後續引用
“\1”表示匹配第一個分組中,最後匹配的最終結果。但有一個前提,最終結果不能是一個。例如用下面圖片說明:因為rXXt在後面沒有出現過,所以嘗試redt,發現redt出現過一次,後面又出現了,符合(“\1”表示匹配第一個分組中,最後匹配的最終結果),所以結果是匹配是字符是redt root redt,而不是rXXt,也不是root。

技術分享圖片

示例5:多次分組後續引用
“\1”表示從左側起第一個左括號以及與之匹配右括號之間的模式所匹配到的字符
“\2”表示小括號裏面的小括號string2

技術分享圖片

示例6:或者
匹配/etc/passwd文件中以r開頭或者以b開頭的行

技術分享圖片

示例7:或者
匹配abc或d

技術分享圖片

示例8:或者
匹配abc或abd

技術分享圖片

練習

1.取出分區利用率最大值

技術分享圖片

2.取出IP地址

技術分享圖片

元字符表

技術分享圖片

技術分享圖片

練習題

技術分享圖片

二.擴展正則表達式

擴展正則表達式和基本正則表達式只是寫法有一點區別,實現的功能都一樣。寫法的區別在於:書寫基本正則表達式時,加上“-E”選項或者grep寫成egrep,然後基本正則表達式後面的“\”都不用寫,就是擴展正則表達式(有一個例外,就是位置錨定的詞首詞尾的“\”不能不寫)。那麽大家可能會說基本正則表達式的書寫太難記了,直接記擴展正則表達式。很嚴重的告訴你不行,因為有些命令或有些腳本等情況,只支持基本正則表達式,或者只支持擴展正則表達式,或者想grep都支持,所以兩個都要掌握。

egrep = grep -E
egrep [OPTIONS] PATTERN [FILE...]

擴展正則表達式的元字符:(參考基本正則表達式,下面是一些示例)

1.字符匹配

. 任意單個字符
[] 指定範圍的字符
[^] 不在指定範圍的字符

2.次數匹配

技術分享圖片

3.位置錨定

技術分享圖片

4.分組

技術分享圖片

練習題

技術分享圖片

示例:顯示IP地址

技術分享圖片

Linux篇 | 文本處理工具和正則表達式(二)