2008年3月7日 星期五

Linux系統基礎指令(二)

下是我在網路上找的一些有關linux的資訊,這個部分比較乏味,我都是用到再來查...
=====================================================

常規表示式
什麼是常規表示式?

常規表示式(也稱為“regex”或“regexp”)是一種用來描述純文字模式的特殊語法。在 Linux 系統上,常規表示式通常被用來尋找純文字的模式,以及對純文字流執行“搜尋-置換”作業以及其它功能。
與 glob 的比較

當我們看到常規表示式時,您可能發現常規表示式的語法看起來與我們上一篇教學(請參閱本教學最後的“參考資料”一節中列出的“第 1 部分”)中研究的“文件名匹配替換”語法相類似。但是,不要讓它欺騙您;它們的類似性只是表面的。雖然常規表示式和文件名匹配替換模式可能看上去相類似,但是它們是根本不同的兩種類型。

簡單子串

記住那個警告,讓我們看一下最基本的常規表示式,簡單子串。為了這樣做,我們要使用 grep,它是一個掃瞄文件內容來尋找適合特定常規表示式的指令。grep 列印與常規表示式匹配的每一行,並忽略與之不匹配的每一行︰

在上面的指令中,grep 的第一個參數是一個常規表示式;第二個參數是一個文件名。grep 讀取 /etc/passwd 中的每一行並對它應用簡單子串常規表示式 bash 來尋找匹配項。如果找到一個匹配項,那麼 grep 列印出整行;否則,忽略該行。
$ grep bash /etc/passwd
operator:x:11:0:operator:/root:/bin/bash
root:x:0:0::/root:/bin/bash
ftp:x:40:1::/home/ftp:/bin/bash


在上面的指令中,grep 的第一個參數是一個常規表示式;第二個參數是一個文件名。grep 讀取 /etc/passwd 中的每一行並對它應用簡單子串常規表示式 bash 來尋找匹配項。如果找到一個匹配項,那麼 grep 列印出整行;否則,忽略該行。

理解簡單子串

一般來說,如果您正在搜尋一個子串,那麼您可以不提供任何“特殊”字元,而只是逐字地指定純文字。只有在子串包括 +、.、*、[、] 或 \(在這樣的情況下,這些字元需要用引號括起來並在它們的前面使用反斜線)才需要做特殊的事情。下面是簡單子串常規表示式幾個其它範例︰

/tmp (掃瞄尋找文字串 /tmp)
"\[box\]"(掃瞄尋找文字串 [box])
"\*funny\*"(掃瞄尋找文字串 *funny*)
"ld\.so"(掃瞄尋找文字串 ld.so)
元字元

使用常規表示式,可以利用元字元來執行比我們至今已研究過的範例複雜得多的搜尋。這些元字元中的一個是 "."(點),它與任何單個字元匹配︰

$ grep dev.hda /etc/fstab
/dev/hda3 / reiserfs noatime,ro 1 1
/dev/hda1 /boot reiserfs noauto,noatime,notail 1 2
/dev/hda2 swap swap sw 0 0
#/dev/hda4 /mnt/extra reiserfs noatime,rw 1 1


在本範例中,文字純文字 dev.hda 沒有出現在 /etc/fstab 中的任何一行中。但是,grep 掃瞄這些行時沒有尋找文字 dev.hda 字串,而是尋找 dev.hda 模式。請記住 "." 將與任何單個字元相匹配。正如您看到的,"." 元字元在功能上等價於 glob 擴充中"?"元字元的工作原理。

使用 []

如果我們希望與比 "." 更具體一點地來匹配字元,那麼我們可以使用 [ 和 ](方括號)來指定要匹配的字元子集︰

$ grep dev.hda[12] /etc/fstab
/dev/hda1 /boot reiserfs noauto,noatime,notail 1 2
/dev/hda2 swap swap sw 0 0


正如您看到的,這個特殊語法的作用與“glob”文件名擴充中的 [] 相同。同樣,這是學習常規表示式的難點之一 ─ 這個語法與“glob ”文件名擴充語法類似,但又不盡相同,它經常給學習常規表示式的人帶來困惑。

使用 [^]

透過使 [ 後面緊跟一個 ^,您可以使方括號中的意思相反。在本例中,方括號將與未列在方括號內的任意字元匹配。同樣,請注意我們在常規表示式中使用 [^] ,而在 glob 中使用 [!] ︰

$ grep dev.hda[^12] /etc/fstab
/dev/hda3 / reiserfs noatime,ro 1 1
#/dev/hda4 /mnt/extra reiserfs noatime,rw 1 1


區別語法

注意下面一點很重要︰方括號內部的語法根本不同於常規表示式其它部分中的語法。例如,如果在方括號內放置一個 "." ,那麼它容許方括號與文字 "." 匹配,就像上面範例中的 1 和 2。比較起來,除非有 \ 作為前綴,否則方括號外面的文字 "." 被解釋為一個元字元。透過輸入如下指令,我們可以利用這一事實來列印 /etc/fstab 中包括文字串 dev.hda 的所有行的清單︰

$ grep dev[.]hda /etc/fstab


或者,我們也可以輸入︰

$ grep "dev\.hda" /etc/fstab


這兩個常規表示式都不可能與您的 /etc/fstab 文件中的任何行相匹配。

“*”元字元

某些元字元本身不匹配任何字元,但卻修改前一個字元的含義。一個這樣的元字元是 * (星號),它用來與前一個字元的零次或者多次重復出現相匹配。這裡是一些範例︰

ab*c(與 abbbbc 匹配但不與 abqc 匹配)
ab*c(與 abc 匹配但不與 abbqbbc 匹配)
ab*c(與 ac 匹配但不與 cba 匹配)
b[cq]*e(與 bqe 匹配但不與 eb 匹配)
b[cq]*e(與 bccqqe 匹配但不與 bccc 匹配)
b[cq]*e(與 bqqcce 匹配但不與 cqe 匹配)
b[cq]*e(與 bbbeee 匹配)
.*(與任何字串匹配)
foo.*(與以 foo 開始的任何字串相匹配)
ac 行與常規表示式 ab*c 相匹配,因為星號也容許前面的表達式(b)出現零次。請注意解釋 * 常規表示式元字元所用的方法與解釋 * glob 字元的方法根本不同。

行的開始和結束

我們在這裡要詳細描述的最後幾個元字元是 ^ 和 $ 元字元,它們用來分別與行的開始和結束相匹配。透過在常規表示式開始處使用一個 ^ ,您可以將您的模式“錨定”在行的開始。在下面的範例中,我們使用 ^# 常規表示式來與以 # 字元開始的任何行相匹配︰

$ grep ^# /etc/fstab
# /etc/fstab: static file system information.
#


完整行常規表示式

可以組合 ^ 和 $ 來與完整的行相匹配。例如,下面的常規表示式將與以 # 字元開始並以 "." 字元結束的行相匹配,在其中間可以有任意多個其它字元︰

$ grep '^#.*\.$' /etc/fstab
# /etc/fstab: static file system information.



在上面的範例中,我們用單引號將我們的常規表示式括起來以阻止 shell 解釋 $ 。在不使用單引號的情況下,grep 甚至沒有機會檢視 $,$ 就從我們的常規表示式上消失了。

沒有留言:

搜尋此網誌