歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> 更多Linux

如何使用 GNU 文本實用程序

  本教程展示如何使用 GNU 文本實用程序集合來處理日志文件、文檔、結構化文本數據庫,以及其他文本性的數據或內容源。本集合中的實用程序經過 UNIX/Linux 開發人員幾十年的改進,已證明是有用的,並且應該是您用於一般文本處理任務的第一選擇。    本教程是為 Linux/UNIX 程序員和系統管理員編寫的,屬於初級至中級水平。    學習本教程的前提條件    對於本教程,您應該一般地熟悉一些類 UNIX 環境,特別是命令行 shell。您本身 不需要是一個程序員:事實上,本教程所講述的技術將對系統管理員和需要處理特殊報告、日志文件、項目文檔以及類似內容的用戶最有用(因此對正式的編程代碼處理不是那麼有用)。在學習本教程的整個過程中,最好隨時打開一個 shell,並試驗本教程所展示的例子以及它們的一些變化形式。     基本概念將在簡介:UNIX 哲學中回顧,您可以在其中復習管道、流、grep 和腳本編程的基礎知識。    David Mertz 對於處理文本具有持久的愛好。 他甚至專門為此編寫了一本書 Text Processing in Python ,並且經常在他為 IBM developerWorks 撰寫的文章和專欄中談及相關的主題。     關於本教程內容的技術問題和意見,請聯系 David Mertz 或者單擊任一屏頂部的"反饋"。 David 的 Web 站點 也是相關信息的一個很好來源。    簡介:UNIX哲學  組合使用小型實用程序來完成大型任務    在諸如 Linux、FreeBSD、Mac OS X、Solaris、AIX 等受 UNIX 啟發的操作系統中,開發環境甚至 shell 和工作環境的背後都存在一種共同的哲學。 這種哲學的要旨就是使用小型實用程序來 完滿地(沒有其他負面影響)完成每個小型任務,然後組合使用這些實用程序來執行復合任務。GNU 項目所產生的大多數產品都支持這種哲學――實際上特定的 GNU 實現已經移植到許多平台上,有些平台甚至傳統上未被看作是 UNIX 類的。然而,Linux 內核必定是更有點單一性的軟件――雖然如此,但是其內核模塊、文件系統、視頻驅動程序等都是相當組件化的。     對於本教程,您應該一般地熟悉一些類 UNIX 環境,特別是命令行 shell。 您本身不需要是一個程序員:事實上,本教程所講述的技術將對系統管理員和需要處理特殊報告、日志文件、項目文檔以及類似內容的用戶最有用(因此對正式的編程代碼處理不是那麼有用)。在學習本教程的整個過程中,最好隨時打開一個 shell,並試驗本教程所展示的例子以及它們的一些變化形式。。     文件和流    如果這種 UNIX 哲學 具有倡導最低限度的模塊化組件和協作的道義論的一面的話,它還具有本體論的一面:"一切皆文件"。抽象地說,文件 只是支持一些操作的對象:首先是讀取和寫入字節,但是也有諸如指出其當前位置和弄清何時到達文件結尾這樣的操作。UNIX 權限模型也是圍繞文件的概念來建立的。    具體地說,文件可以是可記錄介質上的一個具體區域(並具有由文件系統提供的關於其名稱、大小、在磁盤上的位置等的標記)。但是一個文件也可以是 /dev/ 層次結構中的一個虛擬設備,或者通過 TCP/IP 或通過諸如 NFS 這樣的高級協議傳來遠程流。重要的是,特殊文件 STDIN、STDOUT 和 STDERR 可用於讀取或寫到用戶控制台,以及用於在實用程序之間傳遞數據。這些特殊文件可通過虛擬文件名稱來表示,並具有特殊的語法:     STDIN 是/dev/stdin 和/或 /dev/fd/0   STDOUT 是 /dev/stdout 和/或 /dev/fd/1   STDERR 是 /dev/stderr 和/或 /dev/fd/2     UNIX 的文件本體論的優點在於,這裡討論的大多數實用程序都將統一而中立地處理各種數據源,而不管實際位於字節傳輸之下的存儲或傳輸機制是什麼。    重定向和管道    UNIX/Linux 實用程序的通常組合方式是使用管道和重定向。許多實用程序或者自動地或者可選地從 STDIN 接受輸入,並將它們的輸出發送到 STDOUT(特殊的消息則發送到 STDERR)。管道將一個實用程序的 STDOUT 發送到另一個實用程序的 STDIN(或者發送到對同一個實用程序的新的調用)。重定向或者將一個文件的內容作為 STDIN 來讀入,或者將 STDOUT 和/或 STDERR 輸出發送到一個指定的文件。重定向通常用於保存數據以供以後處理或重復處理(對於後者,實用程序將使用 STDIN 重定向)。    在幾乎所有的 shell 中,管道都使用豎線 符號來執行,而重定向都使用大於號和小於號來執行:> 和 ,或使用 &> 來同時將 STDOUT 和 STDERR 重定向到同一個地方。您還可以使用雙大於號(>>)來將輸出附加到一個現有文件的末尾。例如:      源碼:----------------------------------------------------$ foo fname bar - > myout 2> myerr  --------------------------------------------------    這裡,實用程序 foo 可能處理名為 fname 的文件,並輸出到 STDOUT。實用程序 bar 使用了一種普遍用法:當輸出取自 STDIN 而不是取自指定的文件時指定一個短劃線(其他某些實用程序僅接受 STDIN)。來自 bar 的 STDOUT 保存在 myout 中,它的 STDERR 則保存在 myerr 中。    文本實用程序是什麼?    GNU 文本實用程序是一些用於處理和操作文本文件和流的工具集合,它們隨著類 UNIX 操作系統的演進而被提煉,結果證明它們是最有用的。其中的大多數都是早期 UNIX 實現的組成部分,雖然許多已隨著時間的推移而增添了附加的選項。    檔案文件 textutils-2.1 中收集的實用程序包括 27 個工具;然而,GNU 項目維護者最近已決定將這些工具打包為更大的集合 coreutils-5.0 的一部分(預計可能會在後面的版本中這樣做)。在從 BSD 而不是從 GNU 工具演變而來的系統上,相同的實用程序的打包方式可能稍有不同,但是仍然提供了大多數相同的實用程序。    本教程重點介紹傳統上包括在 textutils 中的 27 個實用程序,偶爾會提及和使用一般在類 UNIX 系統上可用的相關工具。然而,我將跳過對實用程序 ptx(permuted index,置換索引)的介紹,因為它的用途太窄,並且包括在這裡也太難於理解。    grep(通用正則表達式處理器)    這個工具本身 並不是 textutils 的組成部分,但是仍然值得特別提及。實用程序 grep 是使用最廣泛的 UNIX 實用程序之一,經常用於文本實用程序的管道輸入或輸出。    grep 所做的工作從一種意義上說非常簡單,從另一種意義上說又相當復雜,難於理解。基本上,grep 識別文件中與某個正則表達式相匹配的行。它有一些開關允許您以各種方式修改輸出, 比如打印周圍的上下文行,給匹配行編號,或者僅識別其中出現匹配項的文件而不是識別單獨的行。本質上,grep 只是用於文件中的行的過濾器(但是功能非常強大)。    grep 的復雜部分是正則表達式,您可以指定它來描述需要的匹配條件。不過這將在另一個教程(請參閱 參考資料 中的 developerWorks 教程"Using regular eXPressions")中講述。還有其他許多實用程序支持正則表達式,但是 grep 是其中最通用的一個工具,因而比起使用其他工具所提供的較弱的過濾器,將 grep 放進管道中通常更容易。一個簡單的 grep 例子如下:     源碼:--------------------------------------------------     $ grep -c [Ss]ystem$ * 2> /dev/null grep :[^0]$       INSTALL:1       aclocal.m4:2       config.log:1       configure:1------------------------------------    這個例子列出包含以"system"結尾的行(或許首字母是大寫的)的文件;同時顯示這些實例出現的次數(也就是如果不為 0 的話)。(實際上,這個例子不會處理大於 9 的計數)。     shell 腳本    雖然文本實用程序旨在以各種有用的格式產生輸出(通常通過命令行開關來修改),但是有些時候能夠顯式地跳轉和循環是很有用的。諸如 bash 這樣的 shell 允許您通過控制流來組合實用程序,從而執行更復雜的任務。shell 腳本對於封裝需要多次執行的復合任務特別有用,特別是那些涉及任務參數化的任務。      解釋 bash 腳本編程顯然超出了本教程的范圍。請參閱 參考資料 以了解 developerWorks 的"Bash by example"系列中對 bash 的介紹。一旦理解了這些實用程序,將它們組合到已保存的 shell 腳本中是相當簡單的。只是出於演示目的,下面提供一個使用 bash 進行流控制的簡單例子:    源碼:----------------------------------------------------       [~/bacchus/articles/scratch/tu]$ cat flow       #!/bin/bash       for fname in `ls $1`; do        if (grep $2 $fname > /dev/null); then         echo "Creating: $fname.new" ;         tr "abc" "ABC" < $fname > $fname.new        fi       done       [~/bacchus/articles/scratch/tu]$ ./flow '*' bash       Creating: flow.new       Creating: test1.new       [~/bacchus/articles/scratch/tu]$ cat flow.new       #!/Bin/BAsh       for fnAme in `ls $1`; do        if (grep $2 $fnAme > /dev/null); then         eCho "CreAting: $fnAme.new" ;         tr "ABC" "ABC" < $fnAme > $fnAme.new        fi       done  面向流的過濾  cat 和 tac    最簡單的文本實用程序只是




Copyright © Linux教程網 All Rights Reserved