Linux 基金會宣布了一個全新的 LFCS(Linux 基金會認證系統管理者(Linux Foundation Certified Sysadmin))認證計劃。這一計劃旨在幫助遍布全世界的人們獲得其在處理 Linux 系統管理任務上能力的認證。這些能力包括支援運作的系統服務,以及第一手的故障診斷、分析,以及為工程師團隊在更新時提供明智的決策。 |
處理 Linux 中的文本流
Linux 将程式中的輸入和輸出當成字元流或者字元序列。在開始了解重定向和管道之前,我們必須先了解三種最重要的I/O(輸入和輸出(Input and Output))流,事實上,它們都是特殊的檔案(根據 UNIX 和 Linux 中的約定,資料流和外圍裝置(裝置檔案)也被視為普通檔案)。
在 > (重定向操作符) 和 | (管道操作符)之間的差別是:前者将指令與檔案相連接配接,而後者将指令的輸出和另一個指令相連接配接。
# command >file
# command1 | command2
由于重定向操作符會靜默地建立或覆寫檔案,我們必須特别小心謹慎地使用它,并且永遠不要把它和管道混淆起來。在 Linux 和 UNIX 系統上管道的優勢是:第一個指令的輸出不會寫入一個檔案而是直接被第二個指令讀取。
在下面的操作練習中,我們将會使用這首詩——《A happy child》(作者未知)
使用 sed
sed 是流編輯器(stream editor)的縮寫。為那些不懂術語的人額外解釋一下,流編輯器是用來在一個輸入流(檔案或者管道中的輸入)執行基本的文本轉換的工具。
sed 最基本的用法是字元替換。我們将通過把每個出現的小寫 y 改寫為大寫 Y 并且将輸出重定向到 ahappychild2.txt 開始。g 标志表示 sed 應該替換檔案每一行中所有應當替換的執行個體。如果這個标志省略了,sed 将會隻替換每一行中第一次出現的執行個體
基本文法:
#sed's/term/replacement/flag'file
我們的樣例:
#sed's/y/Y/g' ahappychild.txt > ahappychild2.txt
如果你要在替換文本中搜尋或者替換特殊字元(如 /,\,&),你需要使用反斜杠對它進行轉義。
例如,我們要用一個符号來替換一個文字,與此同時我們将把一行最開始出現的第一個 I 替換為 You。
#sed's/and/\&/g;s/^I/You/g' ahappychild.txt
在上面的指令中,衆所周知 ^(插入符号)是正規表達式中用來表示一行開頭的符号。
正如你所看到的,我們可以通過使用分号分隔以及用括号包裹來把兩個或者更多的替換指令(并在它們中使用正規表達式)連接配接起來。
另一種 sed 的用法是顯示或者删除檔案中選中的一部分。在下面的樣例中,将會顯示 /var/log/messages 中從6月8日開始的頭五行。
#sed-n '/^Jun 8/ p'/var/log/messages |sed-n 1,5p
請注意,在預設的情況下,sed 會列印每一行。我們可以使用 -n 選項來覆寫這一行為并且告訴 sed 隻需要列印(用 p來表示)檔案(或管道)中比對的部分(第一個指令中指定以“Jun 8” 開頭的行,第二個指令中指定一到五行)。
最後,可能有用的技巧是當檢查腳本或者配置檔案的時候可以保留檔案本身并且删除注釋。下面的單行 sed 指令删除(d)空行或者是開頭為#的行(| 字元對兩個正規表達式進行布爾 OR 操作)。
#sed'/^#\|^$/d' apache2.conf
uniq 指令
uniq 指令允許我們傳回或者删除檔案中重複的行,預設寫到标準輸出。我們必須注意到,除非兩個重複的行相鄰,否則uniq 指令不會删除他們。是以,uniq 經常和一個前置的 sort 指令(一種用來對文本行進行排序的算法)搭配使用。預設情況下,sort 使用第一個字段(用空格分隔)作為關鍵字段。要指定一個不同的關鍵字段,我們需要使用 -k 選項。
樣例
du –sch /path/to/directory/* 指令将會以人類可讀的格式傳回在指定目錄下每一個子檔案夾和檔案的磁盤空間使用情況(也會顯示每個目錄總體的情況),而且不是按照大小輸出,而是按照子檔案夾和檔案的名稱。我們可以使用下面的指令來讓它通過大小排序。
#du-sch /var/* | sort -h
你可以通過使用下面的指令告訴 uniq 比較每一行的前6個字元(-w 6)(這裡是指定的日期)來統計日志事件的個數,而且在每一行的開頭輸出出現的次數(-c)。
#cat/var/log/mail.log |uniq-c -w6
grep 指令
grep 在檔案(或指令輸出)中搜尋指定正規表達式,并且在标準輸出中輸出比對的行。
樣例
顯示檔案 /etc/passwd 中使用者 gacanepa 的資訊,忽略大小寫。
#grep-i gacanepa /etc/passwd
顯示 /etc 檔案夾下所有 rc 開頭并跟随任意數字的内容。
#ls-l /etc |grep rc[0-9]
tr 指令使用技巧
tr 指令可以用來從标準輸入中轉換(改變)或者删除字元,并将結果寫入到标準輸出中。
樣例
把 sortuniq.txt 檔案中所有的小寫改為大寫。
#cat sortuniq.txt |tr[:lower:][:upper:]
壓縮ls –l輸出中的分隔符為一個空格。
#ls-l |tr-s ' '
cut 指令使用方法
cut 指令可以基于位元組(-b選項)、字元(-c)或者字段(-f)提取部分輸入(從标準輸入或者檔案中)并且将結果輸出到标準輸出。在最後一種情況下(基于字段),預設的字段分隔符是一個制表符,但可以由 -d 選項來指定不同的分隔符。
樣例
從 /etc/passwd 中提取使用者賬戶和他們被配置設定的預設 shell(-d 選項允許我們指定分界符,-f 選項指定那些字段将被提取)。
#cat/etc/passwd|cut-d:-f1,7
将以上指令結合起來,我們将使用 last 指令的輸出中第一和第三個非空檔案建立一個文本流。我們将使用 grep 作為第一過濾器來檢查使用者 gacanepa 的會話,然後将分隔符壓縮至一個空格(tr -s ' ')。下一步,我們将使用 cut 來提取第一和第三個字段,最後使用第二個字段(本樣例中,指的是IP位址)來排序之後,再用 uniq 去重。
#last|grep gacanepa |tr-s ‘‘|cut-d’‘-f1,3|sort-k2 |uniq
上面的指令顯示了如何将多個指令和管道結合起來,以便根據我們的要求得到過濾後的資料。你也可以逐漸地使用它以幫助你了解輸出是如何從一個指令傳輸到下一個指令的(順便說一句,這是一個非常好的學習經驗!)
總結
盡管這個例子(以及在目前教程中的其他執行個體)第一眼看上去可能不是非常有用,但是他們是體驗在 Linux 指令行中建立、編輯和操作檔案的一個非常好的開始。請随時留下你的問題和意見——不勝感激!
本文位址:http://www.linuxprobe.com/linux-gnu-sed.html
免費提供最新Linux技術教程書籍,為開源技術愛好者努力做得更多更好:http://www.linuxprobe.com/