歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Unix知識 >> 關於Unix >> 技巧:用Sort和Tsort對文件排序

技巧:用Sort和Tsort對文件排序

日期:2017/3/6 15:48:00   编辑:關於Unix
通過使用 sort 和 tsort,而不是采取使用 Perl 或 Awk 的較復雜的 解決方案 ,可以節省時間,同時還能避免令人頭疼的問題。Jacek Artymiak 將向您說明如何做到這一點。 盡管可以用 Perl 或 Awk 編寫高級排序應用程序,但並非總是有此必要,而且這樣的工作也
  通過使用 sort 和 tsort,而不是采取使用 Perl 或 Awk 的較復雜的解決方案,可以節省時間,同時還能避免令人頭疼的問題。Jacek Artymiak 將向您說明如何做到這一點。
  
  盡管可以用 Perl 或 Awk 編寫高級排序應用程序,但並非總是有此必要,而且這樣的工作也常常令人感到頭疼。使用 sort 命令,您同樣可以實現您所需的大多數功能,而且更容易,它可以對多個文件中的行進行排序、合並文件甚至可以查看是否有必要對它們進行排序。您可以指定排序鍵(用於比較的行中的一部分),也可不指定,後一種情況下 sort 就比較所有行。
  
  因此,如果您想對密碼文件進行排序,就可以使用下列命令(請注意,您不能將輸出直接發送到輸入文件,因為這會破壞輸入文件。這就是為何您需要將它發送到臨時文件中,然後將該文件重命名為 /etc/passwd 的原因,如下所示)。
  
  清單 1. 簡單排序
  $ su -
  # sort /etc/passwd > /etc/passwd-new
  # mv /etc/passwd-new /etc/passwd
  
  如果您想倒轉排序的次序,則應當使用 -r 選項。您還可以用 -u 選項來禁止打印相同的行。
  
  sort 的一個非常實用的特性是它用字段鍵進行排序的能力。字段是一個文本字符串,通過某個字符與其它字段分隔開。例如,/etc/passwd 中的字段是用冒號(:)分隔的。因此,如果願意的話,您可以按照用戶標識、組標識、注釋字段、主目錄或 shell 對 /etc/passwd 進行排序。要做到這一點,請使用 -t 選項,其後跟著用作分隔符的字符,接著是用作排序鍵的字段編號,再跟作為鍵的最後一個字段的編號;例如,sort -t : -k 5,5 /etc/passwd 按照注釋字段對密碼文件進行排序,該字段中存儲了完整的用戶名(如“John Smith”)。而 sort -t : -k 3,4 /etc/passwd 同時使用用戶標識和組標識對同一個文件進行排序。如果您省略了第二個數字,那麼 sort 會假定鍵是從給定的字段開始,一直到每一行的末尾。動手試一試,並觀察其中的區別(當數字排序看上去有錯時,請添加 -g 選項)。
  
  還要注意的是,空白過渡是缺省的分隔符,因此,如果字段已經用空白字符分隔了,那麼您可以省略分隔符,只使用 -t(另注:字段的編號是從 1 開始的)。
  
  為了更好地進行控制,您可以使用鍵和偏移量。偏移量是用點與鍵相分隔的,比如在 -k 1.3,5.7 中,表示排序鍵應當從第 1 個字段的第 3 個字符開始,到第 5 個字段的第 7 個字符結束(偏移量也是從 1 開始編號的)。何時會用得著偏移量呢?嗯,我時常用它來對 Apache 日志進行排序;鍵和偏移量表示法讓我跳過了日期字段。
  
  另一個要關注的選項是 -b,它告知 sort 忽略空白字符(空格、跳格等等)並將行中的第一個非空白字符當做是排序鍵的開始。還有,如果您使用該選項,那麼將從第一個非空白字符開始計算偏移量(當字段分隔符不是空白字符,且字段可能包含以空白字符開頭的字符串時,這非常有用)。
  
  可以用下面這些選項來進一步修改排序算法:-d(只將字母、數字和空白用作排序鍵)、-f(關閉大小寫區分,認為小寫和大寫字符是一樣的)、-i(忽略非打印的 ASCII 字符)、-M(使用三個字母的月份名稱縮寫:JAN、FEB、MAR … 來對行進行排序)和 -n(只用數字、- 和逗號或另外一個千位分隔符對行進行排序)。這些選項以及 -b 和 -r 選項可以用作鍵編號的一部分,在這種情況下,它們只適用於該鍵而非全局,其作用就跟在鍵定義外使用它時一樣。
  
  以鍵編號的用法為例,請考慮:
  
  sort -t: -k 4g,4 -k 3gr,3 /etc/passwd
  
  這條命令將按照組標識對 passwd 文件進行排序,而在組內按照用戶標識進行逆向排序。
  
  但是這並非 sort 的全部能力。如果您所使用的鍵不能用來確定哪一行是在先,那麼它也可以解決這類平局問題。增加一個解決平局問題的提示,請添加另一個 -k 選項,讓它跟在字段和(可選的)偏移量後面,使用與前面用於定義鍵相同的表示法;例如,sort -k 3.4,4.5 -k 7.3,9.4 /etc/passwd 對行進行排序時,使用從第 3 個鍵的第 4 個字符開始到第 4 個鍵的第 5 個字符結束的鍵,然後再采用從第 7 個字段的第 3 個字符到第 9 個字段的第 4 個字符結束的鍵來解決上述難題。
  
  最後一組選項處理輸入、輸出和臨時文件。例如,-c 選項,當它用於 sort -c < file 中時,它檢查輸入文件是否已進行了排序(您也可以使用其它選項),如果已進行了排序,則報告一個錯誤。這樣,在處理可能需要花很長時間進行排序的大型文件之前,可以很方便地對其進行檢查。當您將 -u 選項和 -c 選項一起使用時,會被解釋為一個請求:檢查輸入文件中不存在兩個相同的行。
  
  當您處理大型文件時還有一個很重要的 -T 選項,它用於為臨時文件(這些臨時文件在 sort 完成工作之後會被除去)指定其它目錄,而不是缺省的 /tmp 目錄。
  
  您可以使用 sort 來同時處理多個文件,這樣做的方式基本上有兩種:首先可以使用 cat 來並置它們,如下所示:
  
  cat file1 file2 file3 | sort > outfile
  
  或者,可以使用下面這個命令:
  
  sort -m file1 file2 file3 > outfile
  
  第二種情況有個條件:在將所有輸入文件一起進行 sort -m 之前,每個文件都必須經過排序。這看起來似乎是個不必要的負擔,但事實上這加快了工作速度並節約了寶貴的系統資源。對了,別忘了 -m 選項。在這裡您可以使用 -u 選項來禁止打印相同的行。
  
  如果需要某種更深奧的排序方法,您可能要查看 tsort 命令,該命令對文件執行拓撲排序。拓撲排序和標准 sort 之間的差別如清單 2 所示(您可以從參考資料下載 happybirthday.txt)。
  
  清單 2. 拓撲排序和標准排序之間的差別$ cat happybirthday.txt
  
  Happy Birthday to You!
  
  Happy Birthday to You!
  
  Happy Birthday Dear Tux!
  
  Happy Birthday to You!
  
  $ sort happybirthday.txt
  
  Happy Birthday Dear Tux!
  
  Happy Birthday to You!
  
  Happy Birthday to You!
  
  Happy Birthday to You!
  
  $ tsort happybirthday.txt
  
  Dear
  
  Happy
  
  to
  
  Tux!
  
  Birthday
  
  You!
  當然,對於 tsort 的使用來說,這並非一個非常有用的演示,只是舉例說明了這兩個命令輸出的不同。
  
  tsort 通常用於解決一種邏輯問題,即必須通過觀察到的部分次序預測出整個次序;例如(來自 tsort 信息頁中):
  
  tsort <<EOF a b c d e f b c d e EOF
  
  會產生這樣的輸出
     a
     b
     c
     d
     e
     f

Copyright © Linux教程網 All Rights Reserved