例題三、行首與行尾字元 ^ $
我們在例題一當中,可以查詢到一行字串裡面有 the 的,那如果我想要讓 the 只在行首列出呢? 這個時候就得要使用定位字元了!我們可以這樣做:
[dmtsai@study ~]$ grep -n '^the' regular_express.txt 12:the symbol '*' is represented as start.
此時,就只剩下第 12 行,因為只有第 12 行的行首是 the 開頭啊~此外, 如果我想要開頭是小寫字元的那一行就列出呢?可以這樣:
[dmtsai@study ~]$ grep -n '^[a-z]' regular_express.txt2:apple is my favorite food. 4:this dress doesn't fit me. 10:motorcycle is cheap than car. 12:the symbol '*' is represented as start. 18:google is the best tools for search keyword. 19:goooooogle yes! 20:go! go! Let's go.
你可以發現我們可以捉到第一個字元都不是大寫的!上面的指令也可以用如下的方式來取代的:
[dmtsai@study ~]$ grep -n '^[[:lower:]]' regular_express.txt
好!那如果我不想要開頭是英文字母,則可以是這樣:
[dmtsai@study ~]$ grep -n '^[^a-zA-Z]' regular_express.txt1:"Open Source" is a good mechanism to develop programs. 21:# I am VBird# 指令也可以是: grep -n '^[^[:alpha:]]' regular_express.txt
注意到了吧?那個 ^ 符號,在字元集合符號(括號[])之內與之外是不同的! 在 [] 內代表『反向選擇』,在 [] 之外則代表定位在行首的意義!要分清楚喔! 反過來思考,那如果我想要找出來,行尾結束為小數點 (.) 的那一行,該如何處理:
[dmtsai@study ~]$ grep -n '\.$' regular_express.txt 1:"Open Source" is a good mechanism to develop programs. 2:apple is my favorite food. 3:Football game is not use feet only. 4:this dress doesn't fit me. 10:motorcycle is cheap than car.11:This window is clear. 12:the symbol '*' is represented as start. 15:You are the best is mean you are the no. 1. 16:The world <Happy> is the same with "glad". 17:I like dog. 18:google is the best tools for search keyword. 20:go! go! Let's go.
特別注意到,因為小數點具有其他意義(底下會介紹),所以必須要使用跳脫字元(\)來加以解除其特殊意義! 不過,你或許會覺得奇怪,但是第 5~9 行最後面也是 . 啊~怎麼無法列印出來? 這裡就牽涉到 Windows 平台的軟體對於斷行字元的判斷問題了!我們使用 cat -A 將第五行拿出來看, 你會發現:
[dmtsai@study ~]$ cat -An regular_express.txt | head -n 10 | tail -n 6 5 However, this dress is about $ 3183 dollars.^M$ 6 GNU is free air not free beer.^M$ 7 Her hair is very beauty.^M$ 8 I can't finish the test.^M$ 9 Oh! The soup taste good.^M$ 10 motorcycle is cheap than car.$
我們在第九章內談到過斷行字元在 Linux 與 Windows 上的差異, 在上面的表格中我們可以發現 5~9 行為 Windows 的斷行字元 (^M$) ,而正常的 Linux 應該僅有第 10 行顯示的那樣 ($) 。所以囉,那個 . 自然就不是緊接在 $ 之前喔!也就捉不到 5~9 行了!這樣可以瞭解 ^ 與 $ 的意義嗎? 好了,先不要看底下的解答,自己想一想,那麼如果我想要找出來,哪一行是『空白行』, 也就是說,該行並沒有輸入任何資料,該如何搜尋?
[dmtsai@study ~]$ grep -n '^$' regular_express.txt22:
因為只有行首跟行尾 (^$),所以,這樣就可以找出空白行啦!再來,假設你已經知道在一個程式腳本 (shell script) 或者是設定檔當中,空白行與開頭為 # 的那一行是註解,因此如果你要將資料列出給別人參考時, 可以將這些資料省略掉以節省保貴的紙張,那麼你可以怎麼作呢? 我們以 /etc/rsyslog.conf 這個檔案來作範例,你可以自行參考一下輸出的結果:
[dmtsai@study ~]$ cat -n /etc/rsyslog.conf# 在 CentOS 7 中,結果可以發現有 91 行的輸出,很多空白行與 # 開頭的註解行[dmtsai@study ~]$ grep -v '^$' /etc/rsyslog.conf | grep -v '^#'# 結果僅有 14 行,其中第一個『 -v '^$' 』代表『不要空白行』, # 第二個『 -v '^#' 』代表『不要開頭是 # 的那行』喔!
是否節省很多版面啊?另外,你可能也會問,那為何不要出現 # 的符號的那行就直接捨棄呢?沒辦法!因為某些註解是與設定寫在同一行的後面, 如果你只是抓 # 就予以去除,那就會將某些設定也同時移除了!那錯誤就大了~