標籤:
A gentleman is open-minded and optimistic; a small person is narrow-minded and pessimistic.
"君子坦蕩蕩,小人長戚戚"
參考資料:鳥哥的Linux私房菜 基礎學習篇(第三版)
一、Regex基礎
1、什麼是Regex
Regex(Regular Expression, RE)是對字串操作的一種邏輯公式,就是用一些事先定義好的特定字元及這些特定字元的組合,組成一個“規則字串”,這個“規則字串”用來表達對字串的一種過濾邏輯
2、為什麼要學習Regex
由於其強大的字串處理能力,目前許多工具和程式設計語言都支援Regex,熟練掌握它可以協助我們更高效的完成工作
3、語系對Regex的影響
由於不同的語系其編碼順序不一樣,導致Regex的匹配結果可能不一樣,所以在使用之前應該先確認當前的語系,也可以使用下面這些特殊符號來避免不同語系帶來的問題:
特殊符號 |
代表意義 |
[:alnum:] |
英文大小寫字母及數字,即0-9,A-Z,a-z |
[:alpha:] |
英文大小寫字母,A-Z,a-z |
[:blank:] |
空格與Tab |
[:cntrl:] |
控制按鍵,CR,LF,Tab,Del等 |
[:digit:] |
數字,0-9 |
[:graph:] |
除了空格和Tab外的所有按鍵 |
[:lower:] |
小寫字母,a-z |
[:print:] |
可被列印出來的字元 |
[:punct:] |
標點符號,即 ",‘,?,!,;,:,#,$ |
[:upper:] |
大寫字母,A-Z |
[:space:] |
任何會產生空白的字元,包括空格鍵[Tab] CR等 |
[:xdigit:] |
十六進位的數字類型,包括0-9,A-F,a-f |
4、基礎Regex字元
RE字元 |
意義與範例 |
^word |
意義:以word開頭 範例:尋找以‘#‘開頭的那一行 grep -n ‘^#‘ filename |
word$ |
意義:以word結尾 範例:尋找以‘!‘結尾的那一行 grep -n ‘!$‘ filename |
. |
意義:代表一定有一個任一字元的字元 範例:尋找包含字元‘a‘並且‘a‘後面至少有一個字元的那一行 grep -n ‘a.‘ filename |
\ |
意義:逸出字元,將特殊符號的特殊意義去除 範例:尋找包含單引號的那一行 grep -n \‘ filename |
* |
意義:重複零到無窮多個的前一個字元 範例:尋找包含(es)(ess)(esss)等字串所在的行 grep -n ‘ess*‘ filename |
[list] |
意義:list中的任意一個字元都可以被匹配 範例:尋找包含‘get‘或者‘got‘的行 grep -n ‘g[eo]t‘ filename |
[n1-n2] |
意義:n1-n2範圍內的任意一個字元都可以被匹配 範例:尋找包含數位那一行 grep -n ‘[0-9]‘ filename |
[^list] |
意義:不包含在list中的其他任意一個字元 範例:尋找不包含大寫字母的那一行 grep -n ‘[^A-Z]‘ filename |
\{n,m\} |
意義:連續n到m個的前一個字元,若為\{n\}則是連續n個前一個字元, \{n,\}為連續n到無窮多個前一個字元 範例:尋找包含‘goog‘或者‘gooog‘的那一行 grep -n ‘go\{2,3\}g‘ filename |
5、擴充Regex
擴充Regex可以通過組合功能,將多次尋找變為一次尋找,使用 grep -E 或者 egrep 來支援擴充Regex
6、擴充Regex字元與範例
RE字元 |
意義與範例 |
+ |
意義:重複一個或一個以上的前一個RE字元 範例:尋找(god)(good)(goood)等的字串 egrep -n ‘go+d‘ filename |
? |
意義:零個或一個的前一個RE字元 範例:尋找(gd)(god)這兩個字串 egrep -n ‘go?d‘ filename |
| |
意義:用‘或’的方式找出滿足不同條件的字串 範例:尋找包含‘gd‘或‘good‘或‘dog‘的字串 egrep -n ‘gd|good|dog‘ filename |
() |
意義:找出‘組’字串 範例:尋找包含(glad)或(good)的字串 egrep -n ‘g(la|oo)d‘ filename |
()+ |
意義:多個重複的群組的判別 範例:尋找‘A‘開頭‘C‘結尾,並且‘A‘和‘C‘之間包含一個以上的‘xyz‘的字串 egrep -n ‘A(xyz)+C‘ filename |
二、使用Regex的工具
1、sed工具
sed是一種以行為單位,對資料進行替換、刪除、新增、選取特定行等操作的工具,同時也支援管道
1 用法:sed [-nefr] [動作] 2 參數說明: 3 -n :使用安靜模式,加上-n使得只有經過sed處理的那一行才會被顯示出來 4 -e :直接在命令列模式上進行sed的動作編輯 5 -f :直接將sed的動作寫在一個檔案內,-f filename則可以執行filename內的sed動作 6 -r :sed的動作支援的是擴充Regex的文法(預設為基礎Regex文法) 7 -i :直接修改讀取的檔案的內容,而不是由螢幕輸出
8 動作說明: [n1[,n2]] function 9 n1, n2 :一般代表選擇進行動作的行數,不一定存在10 funciton有下面這些參數:11 a :新增,a後面可接字串,這些字串會在新的一行出現(當前行的下一行)12 c :替換,c後面可接字串,這些字串可以替換n1, n2之間的行13 d :刪除,後面通常不接參數14 i :插入,後接字串,這些字串將會出現在新的一行(當前行的上一行)15 p :列印,將某個選擇的資料列印出來,通常 p 會與 sed -n 一起運行16 s :替換,可以直接進行替換,通常配合Regex使用
範例:
1 ①以行為單位的新增/刪除: 2 $ sed ‘2,5d‘ filename #刪除第2~5行 3 $ sed ‘2a hello world‘ filename #在第二行後面新增一行,內容為“hello world” 4 ②以行為單位的替換與顯示: 5 $ sed ‘2,5c No 2-5 number‘ filename #將第2~5行替換為新的一行,內容為‘No 2-5 number’ 6 $ sed -n ‘2,5p‘ filename #列印第2~5行,如果不加-n則會把所有資料都輸出一遍 7 ③部分資料的尋找並替換:sed ‘s/old/new/g‘ filename #將‘old‘替換為‘new‘ 8 $ sed ‘s/#.*$//g‘ #刪除注釋 9 $ sed ‘/^$/d‘ #刪除空行10 ④直接修改檔案內容:加上-i參數可以直接修改檔案內容(利用這個功能可以在代碼檔案中將多行代碼注釋掉)
推薦閱讀:sed簡明教程
2、awk工具
awk是一種優良的文本處理工具,支援Regex和管道,經常用於將一行分成數個‘欄位’來處理
1 用法:awk ‘條件類型1{動作1} 條件類型2{動作2} ...‘ filename #欄位分隔符號預設為空白格或[tab]鍵
處理流程:
①讀入第一行,並將第一行的資料填入$0,$1,...等變數當中;
②依據條件類型的限制,判斷是否要進行後面的動作;
③做完所有動作與條件類型;
④重複①~③,知道處理完所有資料;
1 #欄位的變數名稱:$0表示整一行,$1代表第一個欄位,以此類推2 #內建變數:NF(每一行擁有的欄位總數)、NR(當前處理的行是第幾行)、FS(目前的分隔字元)3 #邏輯運算子:>、<、>=、<=、==、!=4 #關鍵字:BEGIN、END5 #文法: BEGIN{這裡面放的是執行前的語句}7 # END{這裡面放的是處理完所有行後要執行的語句}9 # {這裡面放的是處理每一行要執行的語句}
範例:
假設有一個檔案名稱為pay.txt,內容如下:
1 # Name 1st 2nd 3th2 # VBird 23000 24000 250003 # DMTsai 21000 20000 230004 # Bird2 43000 42000 41000
如果我要計算每一個人的總額,並且按照一定的格式列印出來,那麼可以這樣:
1 $ cat pay.txt | awk ‘NR==1{printf "%10s %10s %10s %10s %10s\n", $1, $2, $3, $4, "Total" }2 > NR>=2{total = $2 + $3 + $43 > printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total}‘
其中的printf的用法和C語言中的差不多,輸出的結果類似這樣:
1 # Name 1st 2nd 3th Total2 # VBird 23000 24000 25000 72000.003 # DMTsai 21000 20000 23000 64000.004 # Bird2 43000 42000 41000 126000.00
推薦閱讀:AWK 簡明教程
三、其他工具
1、檔案比較工具: diff、cmp、patch
1 # diff:通常用於同一檔案的新舊版本區別上,以行為單位比較2 #用法:diff [-bBi] from-file tofile #比較from-file和to-file並輸出不同的地方3 # cmp:以‘位元組’為單位比較4 #用法:cmp [-s] file1 file2 #按位元組比較file1和file2,並輸出發現的第一個不同點,加上-s輸出所有不同點5 # patch:與 diff 配合製作補丁檔案和升級檔案6 #用法:7 $ diff -Naur oldfile newfile > patch_file #通過比較新舊檔案製作補丁檔案,patch_file通常以.patch為尾碼8 $ patch -pN < patch_file #更新舊檔案,N表示取消幾層目錄9 $ patch -R -pN < patch_file #還原為原來的檔案
2、檔案列印準備: pr
1 # pr:為要列印的檔案設定標題和頁碼2 #用法:pr filename #為filename的輸出加上檔案時間、檔案名稱和頁碼
總結:Regex真的是一種非常有用的工具,由簡單的規則可以搭配出複雜的字串,不過伴隨著高效率的往往是高難度,需要以後不斷的使用才能逐漸掌握
bash shell學習-Regex基礎 (筆記)