基本正則表達式
基本字符(元字符):. * [ \ ^ $(圓點,星號,中括號,反斜線,尖號,dollar號)
-
.
匹配任意字符 -
[ ]
爲集合,其中,圓點,星號和反斜線三個字符在集合中的時候表示自身中括號內,“ - ”減號表示一個區間
[a-zA-Z0-9] # 表示大小寫字母或者數字
如果單純表示減號這個符號,需要將減號放在集合的末尾
[ad-] # 表示a,d,-三個字符
如果要表示中括號自己:
[][] # 表示左右中括號組成的集合
-
^
在集合的開頭表示補集[^a-z] # 表示任意一個非小寫字母的字符;\[^][] 表示任意一個非中括號的字符。
如果不放在開頭,則僅表示自身
[a-z^] # 表示小寫字母和^字符
-
串接:
[0-9].[A-Z]. # 表示一個四字符的字符串,其中第一個字符爲數字,第三個字符爲大寫字母
-
重複:單字符後跟*表示這個字符重複0次或任意次:[A-Z][0-9]*
-
$
在尾部的時候表示僅匹配行尾,不位於行尾的時候僅表示自身:123$
表示匹配文件中行尾的123^
在首部(注意,這裏不是在集合的首部)的時候表示匹配行首,否則僅匹配自身^123 # 表示以123開頭的行
Hel^lo # 僅與字符串Hel^lo匹配
正則表達式擴展BRE:
()
表示分組:
(xy)* # 表示可以重複任意次或者0次的xy串
也可以用於表示邏輯“或”
(pink|green) # 與pink或者green都可以匹配
```powershell
a+ # 加號表示至少一次的a
a? # 問號表示重複0次或者1次的a
\{m,n\} # 表示至少要有m次,最多有n次
[0-9]\{6,8\} # 表示6到8位數字組成的字符串
```
-
一些特殊的預定義:表示特殊含義的組合
-
[[:xdigit:]]
表示十六進制數字的集合 -
\d
表示任意一個數字 -
\D
表示非數字
-
正則篩選工具命令
行篩選grep
grep 的語法格式:grep 模式 文件列表名
基本選項:
-
-n 顯示的時候每行前顯示行號
-
-v 顯示所有不包含查找模式的行(反向搜索)
-
-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相同
整體替換
- \(\)在正則表示中,僅爲了書寫者方便邏輯判斷,沒有實際意義,不會與括號做匹配
[a-z]* -> number
\([a-z]\)* -> number
指令與指令效果相同
- 替換功能:\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 程序文件名 文件名列表`:使用寫好命令的文檔直接運行
程序的結構:程序 執行條件 {動作}
-
一些細節:
- 每一行中,用空格分開的部分,叫做記錄的 域 **
內置變量中, $x 是第x域的內容,$0** 表示這一整行的內容 - 輸入文件的每一行爲一個記錄, 默認變量NR表示行號
- awk自動對每行文本執行條件判斷**(自動循環)**,滿足執行的動作
- 每一行中,用空格分開的部分,叫做記錄的 域 **
-
執行條件:
-
C語言類似的算符:
< > <= == != || && !
-
正則匹配:格式:/regexpr/ ,即兩個斜線中間寫入正則表達式
-
特殊條件:
- 不指定任何條件,對所有文本執行動作
- BEGIN: 在對所有文本行處理之前執行的動作
- END: 在對所有文本行處理之後執行的動作
-
-
動作
-
自定義變量
-
加減乘除以及邏輯操作
-
正則表達式匹配運算符**(用作條件判斷)**:~ 以及!~
例:$2 ~ "\[1-9][1-9]*"
表示 第二個域上的文本,應該是“非0數字開頭的純數字字符串” -
流程控制:
-
條件判斷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的使用區分
總體概括
-
grep的操作對象是以回車爲分解符的“行”。對每一行,進行格式匹配。
-
匹配方式1:精確查找,只有grep支持精確查找
grep test data.log # 在data.log中尋找含有test的行,並輸出
匹配方式2:正則查找
grep 't*st' data.log # 在data.log中尋找符合“t*st”正則式的行並輸出
-
grep在進行匹配的時候,僅僅是進行匹配。也就是說,並不要求這一行嚴格匹配輸入的精確字符串或者正則字符串,只需要這一行裏包括這個條件就可以
-
-
sed的操作對象是數據流。也就是說,對sed命令來說,一個文件就是一個一字排開的超長二進制字符串,他在裏面對輸入的匹配格式進行匹配。如果找到了一段字符串符合匹配,就按照需求對這一段進行修改,其餘部分照常輸出
-
匹配方式:正則查找
sed 's/t*st/TEST/g' data.log # 在data.log文件中尋找含有“t*st”正則式的字符串,並將這個字符串修改爲TEST,其餘部分正常輸出
-
注意,sed和awk的匹配模式裏只有正則匹配(精確匹配被包含在了正則匹配裏)
-
-
awk的操作對象和grep相似,也是行。
-
匹配方式:正則匹配
awk '/t*st/{printf("%d %s",NR,$0);}' data.log # 對data.log文件中含有t*st的行,輸出行號和完整行
-
使用場景
- grep和awk可以篩選出需要的行信息,但如果文章事先沒有分行,則需要sed或者tr指令來分行
- sed能夠對完整文章進行指定修改,但是沒法篩選需要的正則式匹配的句子
- awk如果需要執行的操作很多,可以通過vim編寫一個oper.awk文件,在裏面編寫兩個單引號之間的內容(以上一個例子中的指令爲例,寫入.awk文件中的指令應該爲
/t*st/{printf("%d %s",NR,$0);}
,注意,寫入文件的指令不需要帶單引號),然後採用awk -f oper.awk
來執行即可