細讀shell-6

 在認識了 char. set 這個概念後, 然後再讓我們多認識幾個 RE 中常見的 meta 字符

 

- 錨點(anchor) 

用以標識 RE 於句子中的位置所在. 常見有

^: 表示句首. ^abc 表示以 abc 開首的句子

$: 表示句尾. abc$ 表示以 abc 結尾的句子

\<: 表示詞首. \<abc 表示以 abc 開首的詞

\>: 表示詞尾. abc\> 表示以 abc 結尾的詞

 

- 修飾字符(modifier) 

獨立表示時本身不具意義, 專門用以修改前一個 char. set 的出現次數. 常見有

*: 表示前一個 char. set 的出現次數爲 0 或多次. ab*c 表示 a c 之間可有 0 或多

b 存在

?: 表示前一個 char. set 的出現次數爲 0 1 . ab?c 表示 a c 之間可有 0

1 b 存在

+: 表示前一個 char. set 的出現次數爲 1 或多次. ab+c 表示 a c 之間可有 1

多個 b 存在

{n}: 表示前一個 char. set 的出現次數必須爲 n . ab{3,}c 表示 a c 之間必須

3 b 存在.{n,}: 表示前一個 char. set 的出現次數至少爲 n . ab{3,}c 表示

a c 之間至少有 3 b 存在

{n,m}: 表示前一個 char. set 的出現次數爲 n m . ab{3,5}c 表示 a c

間有 3 5 b 存在

 

然而, 當我們在識別 modifier , 卻很容易忽略"邊界(boundary)"字符的重要性

以剛提到的 ab{3,5}c 爲例, 這裏的 a c 就是邊界字符了

若沒有邊界字符的幫忙, 我們很容以作出錯誤的解讀

比方說: 我們用 ab{3,5} 這個 RE (少了 c 這個邊界字符)可以抓到 abbbbbbbbbbc (a

10 b )這串字嗎

從剛纔的 modifier 我們一般會認爲我們要的 b 3 5 , 若超出了此範圍, 就不是我

們要表達的

因此, 我們或會很輕率的認爲這個 RE 抓不到結果... 

然而答案卻是可以的! 爲甚麼呢

讓我們重新解讀 ab{3,5} 這個 RE 看看

我們要表達的是 a 後接 3 5 b 即可, 3 5 b 後面我們卻沒規定是甚麼

因此在 RE 後面可以是任意的文字, 當然包括 b 也可以啦! (明白了嗎?) 

同樣的, 我們用 b{3,5}c 也同樣可以抓到 abbbbbbbbbbc 這串字的

但我們若使用 ab{3,5}c 這樣的 RE , 由於同時有 a c 這兩個邊界字符, 那就截然不

同了

 

有空再思考一下, 爲何我們用下面這些 RE 都可抓到 abc 這串字呢

x* 

ax*, abx*, ax*b 

abcx*, abx*c, ax*bc 

bx*c, bcx*, x*bc 

...(還有更多...) 

, 若我們在這些 RE 前後分別加一個 ^ $ 這樣的 anchor, 那又如何呢

 

剛學 RE , 只要能掌握上面這些基本的 meta 大蓋就可以入門了

一如前述, RE 是一種規範化的文字表達方式, 主要用於某些文字處理工具之間

grep, perl, vi, awk, sed, 等等. 常用以表示一段連續的字符串, 捕獲之或替換之

然而, 每種工具對 RE 表達式的具體解讀或有一些細微差異, 不過, 基本原則還是一致的

只要能掌握 RE 的基本原理, 那就一理通百理明瞭, 只是在實作時稍加變通即可

 

比方以 grep 來說, Linux 上你可找到 grep, egrep, fgrep 這幾個程序, 其差異大致如

 

* grep: 

傳統的 grep 程序, 在沒有參數的情況下, 只輸出符合 RE 字符串之句子. 常見參數如下

-v: 逆反模示, 只輸出"不含" RE 字符串之句子

-r: 遞歸模式, 可同時處理所有層級子目錄裏的文件

-q: 靜默模式, 不輸出任何結果(stderr 除外. 常用以獲取 return value, 符合爲 true, 否則

false .) 

-i: 忽略大小寫

-w: 整詞比對, 類似 \<word\> . 

-n: 同時輸出行號

-c: 只輸出符合比對的行數

-l: 只輸出符合比對的文件名稱

-o: 只輸出符合 RE 的字符串. (gnu 新版獨有, 不見得所有版本都支持.) 

-E: 切換爲 egrep . 

 

* egrep: 

grep 的擴充版本, 改良了許多傳統 grep 不能或不便的操作. 比方說

- grep 之下不支持 ? + 這兩種 modifier, egrep 則可

- grep 不支持 a|b (abc|xyz) 這類"或一"比對, egrep 則可

- grep 在處理 {n,m} , 需用 \{ \} 處理, egrep 則不需

諸如此類的... 我個人會建議能用 egrep 就不用 grep ...  ^_^ 

 

* fgrep: 

不作 RE 處理, 表達式僅作一般字符串處理, 所有 meta 均失去功能

 好了... 

關於 RE 的入門, 我暫時就介紹到這裏

雖然寫得有點亂, 且有些觀念也不很精確, 不過, 姑且算是對大家有一個交差吧.... ^_^ 

若這兩天還有時間的話, 我再舉些範例來分析一下, 以助大家更好的理解

假如更有可能的話, 也順道爲大家介紹一下 sed 這個工具

(, 這次我不敢作保證了哦... ^_^ )

 

 

 

---------------- 

(順道一提: eval ) 

 

講到 command line 的重組特性, 真的需要我們好好的加以理解的

如此便能抽絲剝襺的一層層的將正個 command line 分析得一清二楚, 而不至於含糊

假如這個重組特性理解下來來, 那麼, 接下來我們介紹一個好玩的命令 --- eval . 

 

我們在不少變量替換的過程中, 常碰到所謂的複式變量的問題, :  

代碼:

a=1 

A1=abc

 

我們都知道 echo $A1 就可得到 abc 這個結果

然而, 我們能否用 $A$a 來取代 $A1 而同樣替換出 abc

 

這個問題我們可用很輕鬆的用 eval 來解決:  

代碼:

eval echo \$A$a

 

說穿了, eval 只不過是在命令行完成替換重組後, 再來一次替換重組罷了... 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章