Linux學習筆記2——正則表達式

基本正則表達式

基本字符(元字符):. * [ \ ^ $(圓點,星號,中括號,反斜線,尖號,dollar號)

  1. .匹配任意字符

  2. [ ]爲集合,其中,圓點,星號和反斜線三個字符在集合中的時候表示自身

    中括號內,“ - ”減號表示一個區間

    [a-zA-Z0-9]  # 表示大小寫字母或者數字
    

    如果單純表示減號這個符號,需要將減號放在集合的末尾

    [ad-]  # 表示a,d,-三個字符
    

    如果要表示中括號自己:

    [][]  # 表示左右中括號組成的集合
    
  3. ^在集合的開頭表示補集

    [^a-z]  # 表示任意一個非小寫字母的字符;\[^][] 表示任意一個非中括號的字符。
    

    如果不放在開頭,則僅表示自身

    [a-z^]  # 表示小寫字母和^字符
    
  4. 串接:

    [0-9].[A-Z].  # 表示一個四字符的字符串,其中第一個字符爲數字,第三個字符爲大寫字母
    
  5. 重複:單字符後跟*表示這個字符重複0次或任意次:[A-Z][0-9]*

  6. $在尾部的時候表示僅匹配行尾,不位於行尾的時候僅表示自身:123$表示匹配文件中行尾的123

    ^在首部(注意,這裏不是在集合的首部)的時候表示匹配行首,否則僅匹配自身

    ^123  # 表示以123開頭的行
    
    Hel^lo  # 僅與字符串Hel^lo匹配
    

正則表達式擴展BRE:

  1. ()表示分組:
   (xy)*  # 表示可以重複任意次或者0次的xy串

也可以用於表示邏輯“或”

(pink|green)  # 與pink或者green都可以匹配
 ```powershell
 a+  # 加號表示至少一次的a
 a? # 問號表示重複0次或者1次的a
 \{m,n\}  # 表示至少要有m次,最多有n次
 [0-9]\{6,8\}  # 表示6到8位數字組成的字符串
 ```
  1. 一些特殊的預定義:表示特殊含義的組合

    1. [[:xdigit:]] 表示十六進制數字的集合

    2. \d表示任意一個數字

    3. \D表示非數字


正則篩選工具命令

行篩選grep

grep 的語法格式:grep 模式 文件列表名

基本選項:

  1. -n 顯示的時候每行前顯示行號

  2. -v 顯示所有不包含查找模式的行(反向搜索)

  3. -i 忽略大小寫

grep -n main *.c # 在當前文件夾下,對所有以.c爲文件名結尾的文件檢索,查找含有字符串“main"的行,並打印行號  ,如果有不止一個.c 文件,還會輸出文件名
       
grep -v  '[Dd]isable'  dev.stat>dev.active  # 將文件dev.stat中所有不包含Disable 和 disable  的行選出,導出到文件dev.active中

注意:grep查找的時候,如果進行的是精準全字匹配,不需要打單引號。如果進行的是正則匹配,則需要對正則式打單引號

ps -ef | grep '^jiang' > progress.txt  # 列出jiang用戶使用的進程名,並將這些進程信息導入到progress文件中

注意事項

grep的作用對象是行文件,準確來說是以回車爲分界。

如果文本沒有進行分行(即:整個文章就是一整段,沒有任何回車),則grep會將整個文章視爲一行進行篩選。

所以,如果需要grep進行匹配,首先要使用別的方式對文章進行分段,可以考慮使用sed流編輯或者tr翻譯命令進行操作

sed 流編輯

基本用法1:sed '命令' 文件列表名

基本用法2:sed -e '命令1' -e '命令2' -e '命令3' 文件列表名: 合併多個命令

基本用法3:sed -f 命令文件 文件名列表:可以將命令寫在一個文件中,在使用時讀取

tail -f pppd.log | sed 's/145\.37\.23\.26/橋西/g'

tail命令列出log文件中新增的內容,sed後的引號內爲指令,指令中,開頭的s/爲替換指令, 後面的145\.37\.23\.26表示被替換的內容,/橋西表示替換的內容爲橋西,/g表示,在這一行中如果這個IP地址多次出現,則全替換

tail -f pppd.log | sed -f sed.cmd  # 其中sed.cmd文件內容爲: 's/145\.37\.23\.26/橋西/g'

效果與例1相同

整體替換

  1. \(\)在正則表示中,僅爲了書寫者方便邏輯判斷,沒有實際意義,不會與括號做匹配
[a-z]* -> number
\([a-z]\)* -> number

指令與指令效果相同

  1. 替換功能:\0 \1 \2…:\0表示整個正則表達式,\x表示正則表達式中第x個括號內的內容
    例:
s/ [\([0-9][0-9]\)] - [\([0-9][0-9]\)] - [\([0-9][0-9]*\)] / \3.\1.\2/g  # 將月-日-年的格式改爲年-月-日

一個完整的實例

對test.c代碼中,root -> val的val替換成num(這裏root可以是其他名稱的結構體變量),且不能影響代碼中作爲普通變量的val

sed -e 's/ \([a-zA-Z_][a-zA-Z0-9_]*\) -> val/ \1 -> num /g' > test.c

awk語言

基本使用:

  1. `awk '程序' 文件名列表`:
  2. `awk -f  程序文件名 文件名列表`:使用寫好命令的文檔直接運行

程序的結構:程序 執行條件 {動作}

  1. 一些細節:

    1. 每一行中,用空格分開的部分,叫做記錄的 域 **
      內置變量中, $x 是第x域的內容,
      $0** 表示這一整行的內容
    2. 輸入文件的每一行爲一個記錄, 默認變量NR表示行號
    3. awk自動對每行文本執行條件判斷**(自動循環)**,滿足執行的動作
  2. 執行條件:

    1. C語言類似的算符:< > <= == != || && !

    2. 正則匹配:格式:/regexpr/ ,即兩個斜線中間寫入正則表達式

    3. 特殊條件:

      • 不指定任何條件,對所有文本執行動作
      • BEGIN: 在對所有文本行處理之前執行的動作
      • END: 在對所有文本行處理之後執行的動作
  3. 動作

    1. 自定義變量

    2. 加減乘除以及邏輯操作

    3. 正則表達式匹配運算符**(用作條件判斷)**:~ 以及!~
      例:$2 ~ "\[1-9][1-9]*"表示 第二個域上的文本,應該是“非0數字開頭的純數字字符串”

    4. 流程控制:

      • 條件判斷if

      • 循環for

      • 打印格式

        print 變量1 變量2...

        printf("格式串", 變量1,變量2, ...)

ps -ef  |  awk '/guest/{printf("%s", $2);}'  # 表示:找到含有guest的行,並輸出每一行第二個域的內容
awk  '{printf("%d  :  %s \n",  NR, $0);}' test.c  # 對test.c這個文件,逐行輸出每一行的內容,並在開頭表明行號
ls -s  |  awk '$1 > 2000 {print $2}'  # 前者羅列所有的文件以及對應的文件大小,後者篩選文件大小大於2000B的文件,並輸出文件名

awk,sed,grep的使用區分

總體概括

  1. grep的操作對象是以回車爲分解符的“行”。對每一行,進行格式匹配。

    1. 匹配方式1:精確查找,只有grep支持精確查找

      grep test data.log  # 在data.log中尋找含有test的行,並輸出
      

      匹配方式2:正則查找

      grep 't*st' data.log  # 在data.log中尋找符合“t*st”正則式的行並輸出
      
    2. grep在進行匹配的時候,僅僅是進行匹配。也就是說,並不要求這一行嚴格匹配輸入的精確字符串或者正則字符串,只需要這一行裏包括這個條件就可以

  2. sed的操作對象是數據流。也就是說,對sed命令來說,一個文件就是一個一字排開的超長二進制字符串,他在裏面對輸入的匹配格式進行匹配。如果找到了一段字符串符合匹配,就按照需求對這一段進行修改其餘部分照常輸出

    1. 匹配方式:正則查找

      sed 's/t*st/TEST/g' data.log # 在data.log文件中尋找含有“t*st”正則式的字符串,並將這個字符串修改爲TEST,其餘部分正常輸出
      
    2. 注意,sed和awk的匹配模式裏只有正則匹配(精確匹配被包含在了正則匹配裏)

  3. awk的操作對象和grep相似,也是行。

    1. 匹配方式:正則匹配

      awk '/t*st/{printf("%d %s",NR,$0);}' data.log  # 對data.log文件中含有t*st的行,輸出行號和完整行
      

使用場景

  1. grep和awk可以篩選出需要的行信息,但如果文章事先沒有分行,則需要sed或者tr指令來分行
  2. sed能夠對完整文章進行指定修改,但是沒法篩選需要的正則式匹配的句子
  3. awk如果需要執行的操作很多,可以通過vim編寫一個oper.awk文件,在裏面編寫兩個單引號之間的內容(以上一個例子中的指令爲例,寫入.awk文件中的指令應該爲/t*st/{printf("%d %s",NR,$0);},注意,寫入文件的指令不需要帶單引號),然後採用awk -f oper.awk來執行即可
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章