正則表達式(grep,awk,sed)和通配符


1. 正則表達式

1. 什么是正則表達式?

正則表達式就是為了處理大量的字符串而定義的一套規則和方法。

通過定義的這些特殊符號的輔助,系統管理員就可以快速過濾,替換或輸出需要的字符串。

Linux正則表達式一般以  為單位處理。

 

2. 為什么要學會正則表達式?

工作中會有大量帶有字符串的文本配置、程序、命令輸出及日志文件等,我們經常會有迫切的需要,從大量的字符串內容中查找符合工作需要的特定的字符串。 

這就需要正則表達式。 

正則表達式就是為了過濾這樣的字符串需求而誕生的。

 

3. 容易混淆的兩個注意事項

正則表達式應用非常廣泛,存在於各種語言中,例如:php, python, java等。

  • Linux系統運維工作中的正則表達式,即Linux正則表達式,最常應用正則表達式的命令就是grep(egrep),sed,awk,換句話說Linux三劍客要想能工作的更高效,那一定離不開正則表達式配合的。
  • 正則表達式和我們常用的通配符特殊字符是有本質區別的。
    • 通配符例子:ls *.log 這里的*就是通配符(表示所有),而不是正則表達式。
 

注意事項:

  1. linux正則表達式一般以 行 為單位處理
  2. alias grep='grep --color=auto',讓匹配的內容顯示顏色
  3. 注意字符集,export LC_ALL=C

 

4. 正則表達式實戰

實戰准備:

  1. 設置grep別名:顏色自動
[root@oldboy test]# alias grep='grep --color=auto'
[root@oldboy test]# alias grep
alias grep='grep --color=auto'
  1. 加載LC_ALL=C,設置字符集
[root@oldboy test]# export LC_ALL=C
[root@oldboy test]# echo $LC_ALL
C
  1. 文本准備:
[root@oldboy test]# cat >>oldboy.log<<EOF   
> I am oldboy teacher!
> I teach Linux.
> 
> I like badminton ball, billiard ball and chinese chess!
> my blog is http://oldboy.blog.51cto.com
> our site is http://www.etiantian.org
> my qq is 49000448.
> 
> not 49000000448
> my god, I am not oldboy,but OLDBOY!
> EOF

 

基礎正則第一波字符說明: 

  1. ^ 以...開頭
    • ^d 以d開頭
    • ^word 匹配以word開頭的內容
    • 在vi/vim編輯器里,^代表一行的開頭 
  2. $ 以...結尾 
    • word$ 匹配以word結尾的內容 
    • 在vi/vim編輯器里,$代表一行的結尾
  3. ^$ 表示空行
 

示例1: 

以m開頭的行(內容):grep '^m' oldboy.log

 

 

以m為結尾的行(內容 ):grep 'm$' oldboy.log

 

 空行,通過-n參數定位到具體的行號:grep '^$' oldboy.log

 

 

用-v參數,排除空行:grep -v '^$' oldboy.log

 

 

基礎正則第二波字符說明:

  1. . 代表且只能代表任意一個字符
  2. \ 轉義符號
    • 讓特殊符號代表其本身
  3. * 重復0個或多個前面的一個字符
    • 例如:o* 匹配,沒有"o",有1個"o",或多個"o"
  4. .* 匹配所有字符
    • 延伸:
      • ^.*以任意多個字符開頭
      • .*$ 以任意多個字符結尾
 

點(.)的含義小結:

  1. 當前目錄
  2. 使得文件生效,相當於source
  3. 隱藏文件
  4. 任意一個字符(grep 正則)
 

示例:

1. 篩選任意一個字符的一行,空行沒有字符,所以過濾排除掉了

grep -n '.' oldboy.log

 

2. "oldb.y"表示"oldb"任意一個字符"y"(不匹配大小寫):grep -n 'oldb.y' oldboy.log

 

3. -i 參數,匹配大小寫: grep -ni 'oldb.y' oldboy.log

 

4. 匹配以"."結尾的行: grep -ni '\.$' oldboy.log

 

5. 匹配所有:".*": grep '.*' oldboy.log -ni

 

6. -o 參數,只顯示匹配的內容,不顯示整行: grep -no 'oldb.y' oldboy.log

 

7. 匹配"o*"的內容:grep -n 'o*' oldboy.log 

 

 

8. 匹配"0*"的內容: grep -n '0*' oldboy.log

 

 

 

基礎正則第三波字符說明:

  1. [abc] 匹配字符集合內的任意一個字符[a-zA-Z],[0-9]。
  1. [^abc] 匹配不包含^ 后的任意個一個字符的內容 中括號內的^ 為取反,注意和中括號外面的^(以...開頭的區別)
    • a\{n,m\} 重復n到m次,前一個重復的字符。
      • 如果用egrep 或 sed -r 可以去掉斜線
      • grep -E 也可以去掉斜線
    • a\{n,\} 重復至少n次,前一個重復的字符。
      • 如果用egrep 或 sed -r 可以去掉斜線
      • grep -E 也可以去掉斜線
    • a\{n\} 重復n次,前一個重復的字符。
      • 如果用egrep 或 sed -r 可以去掉斜線
      • grep -E 也可以去掉斜線
    • a\{,m\} 重復最多m次
      • grep -E 也可以去掉斜線

    注意:egrep 或 sed -r 過濾,一般特殊字符({})可以不轉義

 

示例:

1. 匹配[abc]中任一一個字符 grep '[abc]' oldboy.log

 

 

2. 匹配[^abc]中的字符(非a,非b,非c)grep '[^abc]' oldboy.log

 

3. 匹配"oldboy"或"oldbey",不區分大小寫:grep 'oldb[oe]y' oldboy.log -io

 

 

4. 匹配含數字的行:grep '[0-9]' oldboy.log

 

 

5. 下面分別是:

  • 匹配0(重復3次),其中49000000448是匹配了兩輪,三個0為一組
  • 匹配0 (重復4次)
  • 匹配0 (重復2次),其中49000000匹配了三輪,兩個0為一組
  • 匹配0(重復3到四次)

 

 

匹配0(重復0次到3次):

 

 


基礎正則表達式:元字符意義 BRE(basic regular expression) 

正則表達式(Regular Expression)實際上就是一些特殊符號,賦予了他特定的含義:

  1. ^ 以...開頭

    • ^d 以d開頭
    • ^word 匹配以word開頭的內容
    • 在vi/vim編輯器里,^代表一行的開頭 
  2. $ 以...結尾 

    • word$ 匹配以word結尾的內容 
    • 在vi/vim編輯器里,$代表一行的結尾
  3. ^$ 表示空行

  4. . 代表且只能代表任意一個字符
  5. \ 轉義符號
    • 讓特殊符號代表其本身
  6. * 重復0個或多個前面的一個字符
    • 例如:o* 匹配,沒有"o",有1個"o",或多個"o"
  7. .* 匹配所有字符

    • 延伸:
      • ^.*以任意多個字符開頭
      • .*$ 以任意多個字符結尾
  8. [abc] 匹配字符集合內的任意一個字符[a-zA-Z],[0-9]。

  1. [^abc] 匹配不包含^ 后的任意個一個字符的內容 中括號內的^ 為取反,注意和中括號外面的^(以...開頭的區別)
    • a\{n,m\} 重復n到m次,前一個重復的字符。
      • 如果用egrep 或 sed -r 可以去掉斜線
      • grep -E 也可以去掉斜線
    • a\{n,\} 重復至少n次,前一個重復的字符。
      • 如果用egrep 或 sed -r 可以去掉斜線
      • grep -E 也可以去掉斜線
    • a\{n\} 重復n次,前一個重復的字符。
      • 如果用egrep 或 sed -r 可以去掉斜線
      • grep -E 也可以去掉斜線
    • a\{,m\} 重復最多m次
      • grep -E 也可以去掉斜線

    注意:egrep 或 sed -r 過濾,一般特殊字符({})可以不轉義

 


擴展的正則表達式:grep -E 以及egrep(Extend Regular Expression) 

  1. + 表示重復“一個或一個以上”前面的字符(* 是 0 個或多個)
  2. ? 表示重復 “0個或1個”前面的字符(. 是有且只有1個)
  3. | 表示同時過濾多個字符串
  4. () 分組過濾,后向引用
 

示例: 

1. + 表示重復“一個或一個以上”前面的字符(* 是 0 個或多個)

[root@oldboy test]# grep -Eo "go+d" oldboy.log
god
[root@oldboy test]# grep -Eo "go.d" oldboy.log 
[root@oldboy test]# grep -Eo "go*d" oldboy.log 
god
[root@oldboy test]# grep -Eo "g*d" oldboy.log  
d
d
d
d
d
d
d

2. ? 表示重復 “0個或1個”前面的字符(. 是有且只有1個):

[root@oldboy test]# echo good >>oldboy.log
[root@oldboy test]# egrep "goo?d" oldboy.log --color=auto -o
god
good

[root@oldboy test]# egrep "htt?p" oldboy.log 
my blog is http://oldboy.blog.51cto.com
our site is http://www.etiantian.org

3. | 表示同時過濾多個字符串

[root@oldboy test]# egrep "3306|1521" /etc/services
mysql           3306/tcp                        # MySQL
mysql           3306/udp                        # MySQL
ncube-lm        1521/tcp                # nCube License Manager
ncube-lm        1521/udp                # nCube License Manager

4. () 分組過濾,后向引用:

[root@oldboy test]# egrep "g(o|oo)d" oldboy.log -o
god
good

擴展的正則表達式總結:

  1. + 表示重復“一個或一個以上”前面的字符(* 是 0 個或多個)
  2. ? 表示重復 “0個或1個”前面的字符(. 是有且只有1個)
  3. | 表示同時過濾多個字符串
  4. () 分組過濾,后向引用
 

另外一個需要了解的知識:posix 方括號字符集(挺雞肋的知道就行)

  • [:alnum:] 匹配任意一個字母或數字字符
  • [:lower:] 匹配小寫字母
  • [:xdigit:] 任何一個十六進制數0-9, a-f, A-F
  • [:digit:] 匹配任意一個數字字符
  • [:alpha:] 匹配任意一個字母字符(包含大小寫)
  • [:print:] 任何一個可以打印的字符
  • [:blank:] 空格與制表符
  • [:punct:] 匹配標點符號
  • [:cntrl:] 任何一個控制字符
  • [:space:] 匹配一個包括換行符、回車等在內的所有空白符
  • [:graph:] 匹配任何一個可以看得見的且可以打印的字符
  • [:upper:] 匹配大寫字母
 

過濾小寫字母:

 

 


元字符

元字符(meta character)是一種Perl風格的正則表達式,只有一部分文本處理工具支持它,並不是所有的文本處理工具都支持。

 

 示例:\b 單詞邊界

 

 



2. 通配符

Linux通配符和三劍客的正則表達式是不一樣的,因此,代表的意義也有較大的區別。

 

通配符一般用戶命令行bash環境,而linux正則表達式用於grep, sed, awk場景。

 

通配符

  • * 代表任意0-N個字符,代表所有字符
  • ? 代表任意1個字符
  • ; 連續不同命令的分隔符
  • # 配置文件注釋
  • | 管道:效率並不高
  • ~ 當前用戶的家目錄
  • - 上一次的目錄
    • 例如:cd - 進入上一次的目錄
  • $ 變量前需要加的符號
    • 例如:echo $LANG 輸出變量的內容
  • / 路徑分隔符號,也是根
  • > 1> 重定向,覆蓋
  • >> 追加重定向,追加內容到文件尾部
  • < 輸入重定向(xargs,tr)
  • << 追加輸入重定向(cat)

示例:* 的使用:代表任意0-N個字符,代表所有字符

[root@oldboy /]# mkdir /test
[root@oldboy /]# cd /test
[root@oldboy test]# touch test.sh oldboy.sh oldgirl.sh
[root@oldboy test]# ls
oldboy.sh  oldgirl.sh  test.sh

[root@oldboy test]# ls *.sh  
oldboy.sh  oldgirl.sh  test.sh

[root@oldboy test]# touch gongli.txt
[root@oldboy test]# ls *
gongli.txt  oldboy.sh  oldgirl.sh  test.sh

 

示例:?的使用:代表任意1個字符
[root@oldboy test]# ls ????.sh
test.sh

 

示例:; 是命令之間的分隔符

[root@oldboy test]# whoami;pwd
root
/test

 

其他符號

  • ' 單引號,不具有變量置換功能,輸出時,所見即所得
  • " 雙引號,具有變量置換功能,解析變量后輸出,不加引號相當於雙引號。常用雙引號
  • ` tab鍵上面的鍵,反引號,兩個``中間為命令,會先執行,等價$()。
  • {} 中間為命令區塊組合或內容序列
  • ! 邏輯運算中的“非”NOT
  • && 相當於and,當前一個指令執行成功時,執行后一個指令
  • || 相當於or,當前一個指令執行失敗時,執行后一個指令
  • .. 上一級目錄
  • . 當前目錄
 

示例:單引號,雙引號和反引號

# 單引號:所見即所得
[root@oldboy test]# echo 'date'
date

# 雙引號會解析,但是要加上反引號
[root@oldboy test]# echo "date"
date

# 雙引號內部反引號執行的命令,會解析變量后輸出
[root@oldboy test]# echo "`date`"
Fri Sep  6 05:26:49 CST 2019

# 單引號:所見即所得,即使內部是反引號的命令,輸出仍然是所見即所得。
[root@oldboy test]# echo '`date`'
`date`

 

示例:{}

# 文件備份
[root@oldboy test]# cp test.sh{,.ori}   
[root@oldboy test]# ls test.sh*
test.sh  test.sh.ori

# 批量創建文件
[root@oldboy test]# touch stu{1..5}
[root@oldboy test]# ls stu*
stu1  stu2  stu3  stu4  stu5

# 批量創建目錄,目錄下的子文件等
[root@oldboy test]# mkdir /test/a/{A..C}/{1..3}/end -p
[root@oldboy test]# tree /test/ -d
/test/
└── a
    ├── A
    │   ├── 1
    │   │   └── end
    │   ├── 2
    │   │   └── end
    │   └── 3
    │       └── end
    ├── B
    │   ├── 1
    │   │   └── end
    │   ├── 2
    │   │   └── end
    │   └── 3
    │       └── end
    └── C
        ├── 1
        │   └── end
        ├── 2
        │   └── end
        └── 3
            └── end

 

 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM