Linux sort命令中文手冊(info sort翻譯)

說明:html

(1).本手冊只挑選了info sort中有用的信息進行翻譯,如要查看完完整整的內容,請自行info sort。跨域

(2).譯文中,在括號中使用了"注"的,爲本人所加,非原文內容,助於理解和說明。安全

(3).本文的sort命令爲CentOS 7.2上的,版本爲sort (GNU coreutils) 8.22,有些選項在CentOS 6上不支持,如"--debug"。post

(4).在沒搞懂sort處理字段和排序機制時,強烈建議不要看man sort。性能

(5).sort命令完整的使用方法:文本排序的王者:玩透sort命令測試

本人譯做集合:http://www.cnblogs.com/f-ck-need-u/p/7048359.htmlui


7.1 'sort': Sort text filesspa

===========================命令行

sort命令用於排序、合併或比較給定文件(可給定多個)的全部行,若是沒有給定輸入文件或輸入文件爲"-",則讀取標準輸入。默認狀況下,sort將操做結果打印在標準輸出中。線程

語法:

sort [OPTION]... [FILE]...

sort有3種操做模式:排序(默認)、合併以及檢查是否已經排過序。使用如下3個選項改變操做模式:

'-c'
'--check'
'--check=diagnose-first'

檢查給定文件是否已經排序過:若是檢測出未排序,將輸出診斷信息並以狀態碼1退出,該診斷信息中包含第一個亂序的行。不然以成功狀態退出。最多隻能給定一個檢測文件。

'-C'
'--check=quiet'
'--check=silent'

它相似於"-c",但不會輸出診斷信息。若是文件已排序,則以成功狀態退出,不然以狀態碼1退出。最多隻能給定一個文件。

'-m'
'--merge'

合併多個文件,每一個輸入文件必須已經排序。合併時將根據已排序的結果合併爲各個組。sort通常都用來排序,但仍然提供合併功能,由於它的合併速度很快。

 

sort排序規則爲:按照命令行中給定的字段順序對給定的字段進行排序,排序時根據爲每一個字段分配的排序選項進行排序,直到發現不一樣的排序選項或者排序列結束。若是沒有給定排序key(注:key即爲-k指定的值),則對整行進行排序。最後,若是全部給定的key的比較結果都相等時,將對整行進行徹底默認的排序(注:即以字母升序排序),但"-r"能夠改變此次的升、降序結果。此次排序稱爲"最後的排序"。使用"-s"選項能夠禁止"最後的排序",使得那些排序結果相同的行保留最初的相對順序。"-u"選項一樣也會禁止"最後的排序"。

除非明確指定,不然全部的比較都按照"LC_COLLATE"指定的字符集的排序規則進行排序。

 

退出狀態碼:

0 沒有任何錯誤發生時
1 若是"-c"或"-C"檢測發現輸入數據未排序時
2 發生了錯誤時

若是設置了環境變量"TMPDIR",sort將使用它做爲臨時目錄而不是默認的"/tmp"。"-T"選項將覆蓋該環境變量設置的值。

如下選項影響排序的輸出結果。它們既能夠指定爲全局選項,也能夠做爲key的一部分。若是未指定任何key,則全局選項將做用於整行,不然指定的key將繼承全局選項,除非key自身也指定了選項(注:自身指定了選項的key將覆蓋全局選項)。

爲了考慮可移植性,建議將全局選項指定在"-k"(或"--key")的前面。

'-b'
'--ignore-leading-blanks'

忽略key的前導空白符號(包括空格、製表符)。不給定該選項時,空白符號對"-k"選項指定字符位置有影響(注:例如"-k 2.2"指定的第2個字符多是空白)。

'-f'
'--ignore-case'

將小寫字符看成大寫字符。例如,"b"和"B"是相等的。當和"-u"選項一塊兒使用時(注:重複的行只能輸出一次),那些小寫字符的等價行會被丟棄(注:也就是說,輸出的是大寫字符行)。(目前沒有任何方法能夠拋棄大寫字符的等價行,即便使用"-r"也不行,由於在任什麼時候,"-r"選項都只是反轉最終的排序結果,不會影響排序過程。

'-h'
'--human-numeric-sort'
'--sort=human-numeric'

對文件大小格式進行排序。首先對正負性排序(正數>0>負數),再對大小後綴排序(0<k=K<M<G<T...),最後對數值排序。它不在意轉換精度是1000仍是1024,由於它總會自動不斷擴大到最接近的後綴(注:例如999M和1G比較時將以1000做爲轉換單位,1023M和1G比較時將以1024做爲轉換單位)。

'-M'
'--month-sort'
'--sort=month'

按字符格式的月份進行排序。
An initial string, consisting of any amount of blanks, followed by a month name abbreviation, is folded to UPPER case and compared in the order 'JAN' < 'FEB' < ... < 'DEC'. Invalid names compare low to valid names.

'-n'
'--numeric-sort'
'--sort=numeric'

按數值排序。空字符串""或"\0"被看成無。數值排序是精確排序,不會四捨五入後排序。

(注:數值排序和默認的排序規則所不一樣的是,當key中遇到非數學字符時,如空白、字母、特殊字符等,將直接結束排序(在sort內部認爲找不到匹配值)。也就是說,"-k 2"和"-k 2n"不一樣,雖然這兩個key都會擴展到行尾,前者會從第二個字段一直按字符集順序比較到行尾,然後者可能只對第2字段匹配,由於第二字段和第三字段中間可能有特殊符號,致使數值排序直接結束。

所以,對於"abc 100 200"這樣的輸入,假設字段分隔符爲空格,當指定"-k 2n"時,該key爲"100 200",但因爲中間包含了空白,使得該key的排序在第二字段就結束。若是是"abc 100\0200 200","-k 2n"在排序時,雖然看上去是100200,但卻只對100進行排序,也就是說,若是此時另有一行第2字段值爲110,看上去很大的100200將小於110。測試語句:

echo -e "b 100:200 200\na 110 300" | tr ':' '\0'|sort -t ' ' -k2n -k1

所以,對於"-n"來講,它絕對不可能跨越key的邊界。但默認的排序規則會跨越key起做用。)

'-r'
'--reverse'

反轉比較的結果,使得結果中更大的key更早出現。(注:"-r"不會改變排序行爲,而是將排序結束後的輸出結果進行反轉處理,所以隻影響排序結束後的輸出結果)

'-k POS1[,POS2]'
'--keys=POS1[,POS2]'

指定排序的key,即每行排序的起始和終止字段(若省略POS2,則終止位置爲行尾)。

POS的格式爲"F[.C][OPTS]",其中F表示字段的序號,C表示該字段中字符的序號。字段和字符的位置都從1開始計算。若是POS2的字符位置指定爲0,則表示POS2字段中的最後一個字符。若是POS1中省略".C",則默認值爲1(字段的起始字符),若是POS2中省略".C",默認值爲0(字段的終止字符)。OPTS爲排序選項,這些選項將覆蓋全局選項,使得該key能夠按照獨立的排序選項進行排序。keys能夠跨多個字段。
(注:OPTS指定在POS1和POS2的做用是同樣的,由於一個"-k"指定一個key,不管是POS1仍是POS2中的OPTS都是對這個key有效,但"b"選項除外,見下文)

示例:爲了排序第二個字段,使用"--key=2,2"(-k 2,2)。可以使用"--debug"選項幫助查看、分析和決定每行中被用於排序的字段。

'--debug'

' 顯示每行中用於排序的部分。還會給出額外的信息。

'-o OUTPUT-FILE'
'--output=OUTPUT-FILE'

將排序的輸出結果寫入到OUTPUT-FILE中。通常來講,sort在打開OUTPUT-FILE前讀取完全部輸入,所以能夠安全地將排序結果保存到輸入文件中,就像"sort -o file1 file1"和"cat file1 | sort -o file1"同樣。可是,"-m"選項會在讀取輸入前先打開輸出文件,所以下面的語句是不安全的語句:

"cat file1 | sort -m -o file1 -"

'-s'
'--stable'

禁止sort執行"最後的排序"。在沒有指定字段選項或全局選項時,該選項將不起做用,除非指定的是"-r"選項。
(注:最後的排序:在key的比較結果相同時,sort的最後手段是對整行再進行一次徹底默認的排序,即按照字母、升序對整行作最後排序。這稱爲"最後的排序"。若是未指定任何選項,其自己就是徹底默認的,所以不必再作最後的排序。若是指定的是"-r"選項,因爲"-r"是對最終結果進行反轉排序,所以會影響此次的"最後的排序"的結果)

'-t SEPARATOR'
'--field-separator=SEPARATOR'

當在每行中搜索key的時候,使用SEPARATOR字符做爲字段的分隔符。默認狀況下,字段是由空白字符和非空白字符之間的空字符串分割而來的。

所以,若是輸入行爲" foo bar",默認將切分爲兩個字段" foo"和" bar",(注:空白和非空白字符之間的空字符爲行開頭和"oo"後的位置)。字段分隔符不是分隔後字段中的內容,所以"sort -t ' '"對" foo bar"分隔時,將分割爲3個字段:空字段、"foo"和"bar"。可是,每一個單獨的字段都是擴展到行結尾的,就像"-k 2",或像"-k 2,3"包含了範圍的字段,它們都在擴展的時候保留字段分隔符。
(注:以sort -t ' '爲例,"-k 2"實際上表示的是"foo bar",它擴展到行尾,且中間的字段分隔符被保留。而"-k 1,2"實際上表示的是" foo",由於明確指定了這個key到第二個字段結束,但中間的字段分隔符仍保留)
若是要指定字段分隔符爲空,則使用"\0",例如"sort -t '\0'"。

'--parallel=N'

設置sort運行的並行線程數爲N。默認N設置爲可得到的cpu個數,但最大限制爲8,由於超過8以後帶來的性能收益遞減。

'-u'
'--unique'

通常狀況下,"-u"將僅輸出排序後重復行的第一行。該選項會禁止"最後的排序"(注:見前文譯文)。

"sort -u"和"sort | uniq"是等價的,但擴展了更多選項後將可能不等價,例如,"sort -n -u"只會檢查數值部分的惟一性,但"sort -n | uniq"在sort對行的數值排序後,uniq將檢查整個行的惟一性。

'-z'
'--zero-terminated'

使用"\0"分割每行而不是使用換行符。

 

"-k"指定的key後面能夠指定"bfhgnr"等選項,這種狀況下,該key將不會繼承全局選項。除了"b"選項,全部的選項都做用於整個key,不管該選項是寫在POS1仍是POS2上。若是指定了"b"選項,它僅獨立做用於POS1或POS2上,但若是繼承了全局的"-b",則會做用於整個key上。若是輸入行中包含了前導空白字符,且沒有使用"-t"選項,"-k"一般會結合"-b"或某些隱含了忽略前導空白字符的選項(ghn)一塊兒使用,不然前導空白字符可能會致使劃分的字段很是混亂。

若是POS中指定的字段或字符位置超出了行尾或字段,則該key爲空。若是指定了"-b"選項,".C"部分將從字段的第一個非空白字符開始計算。

如下是一些示例,用於說明不一樣選項的結合使用:

  •  按數值排序,並降序(reverse)
sort -n -r
  •  按字母排序,忽略第一和第二字段,且忽略第三字段的前導空白。此處使用了單個key,該key從第三字段非空白字符開始,一直擴展到行的結尾。這一整個key都採用字母排序。
sort -k 3b
  • 對第二字段按數值排序,並經過指定第五字段的第三、4字符間按字母排序來解除按數值排序的規則。使用":"做爲字段分隔符。
sort -t : -k 2,2n -k 5.3,5.4

(注:任什麼時候候,只想對某字段進行排序時,都建議明確指定其起始和結束位置)

注意,若是寫的是"-k 2n"而不是"-k 2,2n",該key將從第二字段一直擴展到行尾,這是主排序key,而副排序key"-k 5.3,5.4"在主排序key的排序基礎上再按照字母排序。絕大多數狀況下,讓key向後擴展通常不是所指望的行爲。

還需注意,"n"選項做用範圍爲第一個key。這等價於"-k 2n,2"或"-k 2n,2n"。全部的修飾符,除了"-b",不管寫在pos1仍是pos2,都會做用於整個key。

(注:因爲n選項沒法跨越key,所以上面即便寫成了"-k 2n"也是等價的,但下面兩個命令則不同:

sort -t : -k 2 -k 5.3,5.4n
sort -t : -k 2,2 -k 5.3,5.4n

因爲默認的字符集排序規則會跨越key,第一條命令中主key從第2字段開始,直到行尾結束,因而會先對整個key按字符排序,而後在此基礎上再對副key按數值排序。
再以下面的例子:即便主key的字段在副key的字段後面,副key因爲是作字符集排序,因此仍會跨越主key。)

sort -t : -k 5n -k 2
  • 對/etc/passwd文件的第5字段排序,並忽略前導空白。若是第5字段排序結果相等,則進一步按數值對第3字段的uid進行排序。字段分隔符爲":"。
sort -t : -k 5b,5 -k 3,3n /etc/passwd
sort -t : -n -k 5b,5 -k 3,3 /etc/passwd
sort -t : -b -k 5,5 -k 3,3n /etc/passwd

以上三個命令是等價的。第一個命令指定了第一個key的POS1要忽略前導空白,且第二個key要按照數值排序。另外兩個命令中,缺乏選項的key將繼承全局選項。此處繼承之因此能正確工做,是由於"-k 5b,5b"和"-k 5b,5"是等價的。

  • 對一系列日誌文件進行排序,主排序key爲IPv4,副排序key爲時間戳。若是兩行的主、副key都徹底一致,則按照文件被讀取時的相對順序輸出。日誌文件包含的行格式大體以下:

4.150.156.3 - - [01/Apr/2004:06:31:51 +0000] message 1
211.24.3.231 - - [24/Apr/2004:20:17:39 +0000] message 2

使用單個空格能夠精確分割這些字段。IPV4地址列按照字典順序排序,例如212.61.52.2小於212.129.233.201,由於61小於129。

sort -s -t ' ' -k 4.9n -k 4.5M -k 4.2n -k 4.14,4.21 file*.log |\
sort -s -t '.' -k 1,1n -k 2,2n -k 3,3n -k 4,4n

該示例沒法僅使用一個sort語句實現,由於IPV4地址須要使用"."分隔,而時間戳須要使用空格分隔。所以,使用兩個sort語句:第一個sort語句按照時間戳排序,第二個語句按照IPV4排序。第一個sort命令中使用"-k"將每一個字段進行隔離,先按照年排序,再按照月份排序,接着是日,最後對"時:分:秒"排序。除了"時:分:秒"這個key,其他的key都不必指定key的結束位置,由於"n"和"M"選項做用範圍不能跨域每一個key的左邊界。第二個sort命令是對ipv4地址按照字典順序排序的。第二個sort語句中使用了"-s"選項,以防止主排序key的關係被副排序key破壞,第一個sort語句中使用"-s"選項是爲了保證兩個sort語句在"-s"屬性上的一致性。

(注:因爲n選項沒法跨越key邊界和非數學字符,所以上面第二個sort命令和下面的命令是等價的:)

sort -s -t '.' -n -k1 -k2 -k3 -k4
相關文章
相關標籤/搜索