無論是工作中使用還是應(yīng)付各種面試,linux sort 都是必須要掌握的 linux 基本命令之一。尤其是 linux sort -k 命令,經(jīng)常會被搞暈,索性好好研究一下 sort 命令
成都創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的奎文網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
語法:
選項:
參數(shù)就不一一介紹了,直接上例子,首先先看下原始的排序數(shù)據(jù)
cat sort.log
1、打印從哪列開始是亂序
sort -c sort.log; echo $?
sort -C sort.log; echo $?
其中,返回結(jié)果 1,表示文件不是已經(jīng)排序好的文件
2、默認(rèn)排序( 整行進(jìn)行ASCII字符升序)
sort sort.log
3、高能來了,讓人迷糊的 k 語法,首先看下 k 的語法格式
這個語法格式可以被其中的逗號(”,”)分為兩大部分,Start部分和End部分
Start和End部分都由三部分組成,其中的Modifier部分就是類似n和r的選項部分,可省略
FStart、Fend,表示使用的域,而CStart則表示在FStart域中從第幾個字符開始算"排序首字符",同理,CEnd表示結(jié)尾的第幾個字符是排序末尾字符,.CStart、.CEnd是可以省略的,分別表示從本域的開頭部分開始、到本域的域尾結(jié)束,CEnd設(shè)定為0,也是表示結(jié)尾到域尾??谡f無憑,上幾個例子吧
3.1 對第三列進(jìn)行排序,如果不加n,按照 ASCII字符排序
sort -t $'\t' -k 3 sort.log
3.2 加n后,按照數(shù)值排序
sort -t $'\t' -k 3n sort.log
3.3 不指定 FEnd 時,多個 -k 從前往后排序可以,從后往前不行
從后往前,多個 -k,數(shù)據(jù)符合預(yù)期
sort -t $'\t' -k 3n -k 1 sort.log
從后往前,多個 -k ,第三列相同時,按照第一列降序排列,數(shù)據(jù)符合預(yù)期
sort -t $'\t' -k 3n -k 1r sort.log
更換成從前往后
sort -t $'\t' -k 1 -k 3n sort.log
sort -t $'\t' -k 1 -k 3nr sort.log
通過 sort -t $'\t' -k 1 -k 3n sort.log 和 sort -t $'\t' -k 1 -k 3nr sort.log 返回的結(jié)果發(fā)現(xiàn),在第一列相等時,無論其三列是正序排列,還是逆序排列,結(jié)果都一樣,說明后邊的 -k 未生效
當(dāng)指定 FEend 后
sort -t $'\t' -k 1,1 -k 3nr sort.log
3.4 作用域
緊跟在字段后的選項(如"-k3n"的"n"和"-k2nr"的"n","r")稱為私有選項,使用短橫線寫在字段外的選項(如"-n"、"-r")為全局選項。當(dāng)沒有為字段分配私有選項時,該排序字段將繼承全局選項,所有選項包括但不限于"bfnrhM"
除了"b"選項外,其余選項無論是指定在FStart還是FEnd中都是等價的,對于"b"選項,指定在FStart則作用于FStart,指定在FEnd則作用于FEnd
sort -t $'\t' -k1r,2 sort.log ,可以看出一、二列都是倒敘排列
3.5 注意
指定n選項按數(shù)值排序時, 由于"n"選項只能識別數(shù)字和負(fù)號"-",當(dāng)排序時遇到無法識別字符時,將導(dǎo)致該key的排序立即結(jié)束,n選項絕對不會跨域進(jìn)行比較
默認(rèn)情況下,sort會進(jìn)行一次 "最后的排序" ,按照默認(rèn)規(guī)則對整行進(jìn)行一次排序,這次排序稱為"最后的排序"
sort -t $'\t' -k3n sort.log ,在第三列相等時,整行會按照 ASCII 進(jìn)行最后的升序排列
sort -t $'\t' -k3,4n -s sort.log ,加了 -s 后,不會進(jìn)行最后的排序(1000相同時,e在b的前邊了),而是保留原排序
3.6 按照某個域中的第n個字符進(jìn)行排序
sort -t $'\t' -k2.3,2.3 sort.log ,按第二列第三個字符進(jìn)行排序
4、 -h 使用易讀性數(shù)字(例如:2K、1G)
sort -t $'\t' -k5h sort.log
sort -t $'\t' -k2,2 sort.log|uniq
sort -t $'\t' -k2,2 -u sort.log 會對第二列進(jìn)行去重,而 sort -t $'\t' -k2,2 sort.log|uniq 會對整行進(jìn)行去重(當(dāng)然uniq也可以按照第二列進(jìn)行去重)
sort整理完了,歡迎大牛指教
sort是Linux命令,主要用于排序文件、對已排序的文件進(jìn)行合并,并檢查文件以確定它們是否已排序
語法
sort [ -A ] [ -b ] [ -c ] [ -d ] [ -f ] [ -i ] [ -m] [ -n ] [ -r ] [ -u ] [ -o OutFile ] [ -t Character ] [ -T Directory ] [ -y [ Kilobytes ] ] [ -z RecordSize ] [ [ + [ FSkip ] [ .CSkip ] [ b ] [ d ] [ f ] [ i ] [ n ] [ r ] ] [ - [ FSkip ] [ .CSkip ] [ b ] [ d ] [ f ] [ i ] [ n ] [ r ] ] ] ... [ -k KeyDefinition ] ... [ File ... ]
sort 命令對 File 參數(shù)指定的文件中的行排序,并將結(jié)果寫到標(biāo)準(zhǔn)輸出。如果 File 參數(shù)指定多個文件,那么 sort 命令將這些文件連接起來,并當(dāng)作一個文件進(jìn)行排序。-(減號)代替文件名指定標(biāo)準(zhǔn)輸入。如果您不指定任何文件名,那么該命令對標(biāo)準(zhǔn)輸入排序??梢允褂?-o 標(biāo)志指定輸出文件。 如果不指定任何標(biāo)志,sort 命令基于當(dāng)前語言環(huán)境的整理順序?qū)斎胛募乃行信判颉?/p>
排序關(guān)鍵字
排序關(guān)鍵字是輸入行的一部分,由字段號和列號指定。字段是輸入行的組成部分,由字段分隔符分隔。缺省字段分隔符是由一個或多個連續(xù)空格字符組成的序列。使用 -t 標(biāo)志可指定不同的字段分隔符。在 C 語言和英語語言環(huán)境下,制表符和空格字符都是空格符。 使用排序關(guān)鍵字時,sort 命令首先根據(jù)第一個排序關(guān)鍵字的內(nèi)容對所有行排序。然后,根據(jù)第二個排序關(guān)鍵字的內(nèi)容,對所有第一個排序關(guān)鍵字相同的行排序,如此進(jìn)行下去。按照排序關(guān)鍵字在命令行中出現(xiàn)的順序給它們編號。如果兩行對所有排序關(guān)鍵字的排序都相同,則對全部行依據(jù)當(dāng)前語言環(huán)境的整理順序進(jìn)行比較。 對字段中的列進(jìn)行編號時,缺省字段分隔符中的空格符將作為后繼字段計數(shù)。前導(dǎo)空格不計作第一字段的一部分,-t 標(biāo)志指定的字段分隔符將不作為字段的一部分計數(shù)??墒褂?-b 標(biāo)志忽略前導(dǎo)空格符。 可使用下列兩種方法定義排序關(guān)鍵字: * -k KeyDefinition * FSkip.CSkip(廢棄版本)。 使用 -k 標(biāo)志定義排序關(guān)鍵字 -k KeyDefinition 標(biāo)志采用下列形式: -k [ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ] 排序關(guān)鍵字包括所有以 FStart 變量指定的字段和 CStart 變量指定的列開頭的及以 FEnd 變量指定的字段和 CEnd 變量指定的列結(jié)束的字符。如果不指定 Fend,就假定行的最后一個字符。如果不指定 CEnd,就假定 FEnd 字段的最后一個字符。KeyDefinition 變量中的任何字段號或列號都可以省略。缺省值為: FStart 行開頭 CStart 字段第一列 FEnd 行結(jié)束 CEnd 字段最后一列 如果字段間有任意空格,sort 就把它們看作分隔的字段。 Modifier 變量的值可以是字母 b、d、f、i、n 或 r 中的一個或多個。修飾符僅應(yīng)用于它們連接的字段定義,與同一字母的標(biāo)志有同樣的效果。修飾符字母 b 僅應(yīng)用于其連接的字段定義的末尾。例如: -k 3.2b,3r 指定排序關(guān)鍵字,從第三字段的第二非空格列開始并擴(kuò)展至第三字段結(jié)束,對這個關(guān)鍵字的排序以逆向整理順序完成。如果 FStart 變量和 CStart 變量在命令行末尾以外或在 FEnd 變量和 CEnd 變量之后,那么該排序關(guān)鍵字被忽略。 排序關(guān)鍵字也可用下列方式指定: [+[FSkip1] [.CSkip1] [Modifier] ] [-[FSkip2] [.CSkip2] [Modifier]] +FSkip1 變量指定跳過的字段數(shù)以到達(dá)排序關(guān)鍵字第一字段,+CSkip 變量指定在該字段中跳過的列數(shù)以到達(dá)排序關(guān)鍵字第一個字符。-FSkip 變量指定跳過的字段數(shù)以到達(dá)排序關(guān)鍵字后的第一個字符,-CSkip 變量指定在該字段中跳過的列數(shù)。可以省略任何要跳過的字段和列。缺省值為: FSkip1 行開頭 CSkip1 零 FSkip2 行結(jié)束 CSkip2 零 Modifier 變量指定的修改量與 -k 標(biāo)志關(guān)鍵字排序定義中的相同。 因?yàn)?+FSkip1.CSkip1 變量指定到達(dá)排序關(guān)鍵字前要跳過多少字段和列,所以這些變量指定的字段號和列號通常比排序關(guān)鍵字本身的字段號和列號小 1。例如: +2.1b -3r 指定排序關(guān)鍵字,從第三字段的第二非空格列開始并擴(kuò)展至第三字段結(jié)束,對這個關(guān)鍵字的排序以逆向整理順序完成。語句 +2.1b 指定跳過兩個字段,然后跳過前導(dǎo)空格和另一列。如果 +FSkip1.CSkip1 變量在命令行末尾以外或在 -FSkip2.CSkip2 變量之后,則忽略該排序關(guān)鍵字。 注:一行的最大字段數(shù)為 10。
標(biāo)志
注:在任何排序關(guān)鍵字定義前出現(xiàn)的 -b、-d、-f、-i、-n 或 -r 標(biāo)志應(yīng)用于所有排序關(guān)鍵字。-b、-d、-f、-i、-n 或 -r 標(biāo)志都不能單獨(dú)出現(xiàn)在 -k KeyDefinition 之后;如果它們作為修飾符連接 KeyDefinition 變量,那么就只應(yīng)用于連接排序關(guān)鍵字。如果這些標(biāo)志之一跟隨在 +Fskip.Cskip 或 -Fskip.Cskip 排序關(guān)鍵字定義后,那么該標(biāo)志只能用于此排序關(guān)鍵字。 -A 使用 ASCII 整理順序代替當(dāng)前語言環(huán)境的整理順序在逐字節(jié)的基礎(chǔ)上排序。 -b 忽略前導(dǎo)空格和制表符,找出字段的第一或最后列。 -c 檢查輸入是否已按照標(biāo)志中指定的排序規(guī)則進(jìn)行排序。如果輸入文件排序不正確,就返回一個非零值。 -d 使用字典順序排序。比較中僅考慮字母、數(shù)字和空格。 -f 比較前將所有小寫字母改成大寫字母。 -i 比較中忽略所有非打印字符。 -k KeyDefinition 指定排序關(guān)鍵字。KeyDefinition 選項的格式為: [ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ] 排序關(guān)鍵字包括所有以 FStart 變量指定的字段和 CStart 變量指定的列開頭的字符及以 FEnd 變量指定的字段和 CEnd 變量指定的列結(jié)束的字符。Modifier 變量的值可以是 b、d、f、i、n 或 r。 修飾符與同一字母的標(biāo)志等價。 -m 只合并多個輸入文件;假設(shè)輸入文件已經(jīng)排序。 -n 按算術(shù)值對數(shù)字字段排序。數(shù)字字段可包含前導(dǎo)空格、可選減號、十進(jìn)制數(shù)字、千分位分隔符和可選基數(shù)符。對包含任何非數(shù)字字符的字段進(jìn)行數(shù)字排序會出現(xiàn)無法預(yù)知的結(jié)果。 -o OutFile 將輸出指向 OutFile 參數(shù)指定的文件,而不是標(biāo)準(zhǔn)輸出。OutFile 參數(shù)值可以與 File 參數(shù)值相同。 -r 顛倒指定排序的順序。 -t Character 指定 Character 為單一的字段分隔符。 -u 禁止按照排序關(guān)鍵字和選項的所有等同排序(每一組行中一行除外)。 -T Directory 將創(chuàng)建的所有臨時文件放入 Directory 參數(shù)指定的目錄中。 -y[Kilobytes] 用 Kilobytes 參數(shù)指定的主存儲的千字節(jié)數(shù)啟動 sort 命令,并根據(jù)需要增加存儲量。(如果 Kilobytes 參數(shù)指定的值小于最小存儲站點(diǎn)或大于最大存儲站點(diǎn),就以這個最小存儲站點(diǎn)或最大存儲站點(diǎn)取代)。如果省略 -y 標(biāo)志,sort 命令以缺省的存儲大小啟動。-y0 標(biāo)志用最小存儲啟動,而 -y 標(biāo)志(不帶 Kilobytes 值)用最大存儲啟動。sort 命令使用的存儲量顯著地影響性能。以大存儲量對小文件排序?qū)⒑芾速M(fèi)。 -z RecordSize 如果正在排序的任一行大于缺省的緩沖區(qū)大小,要防止出現(xiàn)異常終止。指定 -c 或 -m 標(biāo)志時,省略排序階段,使用系統(tǒng)的缺省緩沖大小。如果已排序行超出這一大小,排序異常終止。-z 選項指定排序階段最長行的記錄,因而可在合并階段分配足夠的緩沖區(qū)。RecordSize 必須指明等于或大于要合并的最長行的字節(jié)值。
[編輯本段]退出狀態(tài)
該命令返回以下出口值: 0 所有輸入文件成功輸出,或指定了 -c 且正確排序了輸入文件。 1 在 -c 選項下,文件沒有按指定排序,或如果指定 -c 和 -u 選項,找到了兩個具有相同關(guān)鍵字的輸入行。 1 發(fā)生錯誤。
[編輯本段]示例
1.排序fruits
1. 要在 LC_ALL、LC_COLLATE 或 LANG 環(huán)境變量設(shè)置為 En_US 的情況下排序 fruits 文件,請輸入: LANG=En_US sort fruits 此命令序列顯示以升序詞典順序排序的 fruits 文件的內(nèi)容。每一列的字符,包括空格、數(shù)字和特殊字符都經(jīng)一一比較。例如,如果 fruits 文件包含文本: banana orange Persimmon apple %%banana apple ORANGE sort 命令顯示: %%banana ORANGE Persimmon apple apple banana orange 在 ASCII 整理序列中,%(百分號)在大寫字母前,大寫字母在小寫字母前。如果您當(dāng)前的語言環(huán)境指定 ASCII 之外的字符集,結(jié)果可能不同。
2. 以字典順序排序
sort -d fruits 此命令序列排序和顯示 fruits 文件的內(nèi)容,并且只比較字母、數(shù)字和空格。如果 fruits 文件與示例 1 相同,那么 sort 命令顯示: ORANGE Persimmon apple apple %%banana banana orange -d 標(biāo)志忽略 %(百分號)字符,因?yàn)樗皇莻€字母、數(shù)字或空格。(即 %%banana 被 banana 取代)。
3.大小寫字母分組
要將包含大寫字母和具有類似小寫行的特殊字符行分組,請輸入: sort -d -f fruits -d 標(biāo)志忽略特殊字符,-f 標(biāo)志忽略大小寫差異。將 LC_ALL、LC_COLLATE 或 LANG 環(huán)境變量設(shè)置為 C 的情況下,fruits 文件的輸出結(jié)果變?yōu)椋? apple apple %%banana banana ORANGE orange Persimmon
4. 除去重復(fù)行排序
sort -d -f -u fruits -u 標(biāo)志告訴 sort 命令除去重復(fù)的行,使文件中的每一行唯一。此命令序列顯示: apple %%banana orange Persimmon 不僅除去重復(fù)的 apple,而且也除去了 banana 和 ORANGE。除去這些是因?yàn)?-d 標(biāo)志忽略 %% 這個特殊字符,-f 標(biāo)志忽略大小寫差異。
5. 除去重復(fù)的實(shí)例
sort -u +0 -d -f +0 fruits 輸入 +0 -d -f 完成的排序與示例 3 中 -d -f 的排序類型相同,+0 進(jìn)行另一項比較以區(qū)分不一樣的行。這防止 -u 標(biāo)志將它們除去。 示例 1 所示的 fruits 文件中,添加的 +0 將 %%banana 與 banana 及 ORANGE 與 orange 區(qū)分開來。然而,apple 的兩個實(shí)例是相同的,所以其中之一被刪除。 apple %%banana banana ORANGE orange Persimmon
6. 指定分隔字段的字符
sort -t: +1 vegetables 此命令序列排序 vegetables 文件,對每一行上第一個冒號后的文本進(jìn)行比較。+1 告訴 sort 命令忽略第一字段,從第二字段的開始到該行的結(jié)束進(jìn)行比較。-t: 標(biāo)志告訴 sort 命令冒號分隔字段。如果 vegetables 包含: yams:104 turnips:8 potatoes:15 carrots:104 green beans:32 radishes:5 lettuce:15 那么,將 LC_ALL、LC_COLLATE 或 LANG 環(huán)境變量設(shè)置為 C 的情況下,sort 命令將顯示: carrots:104 yams:104 lettuce:15 potatoes:15 green beans:32 radishes:5 turnips:8 注意數(shù)字沒有按照數(shù)字排序。當(dāng)用字典式分類從左至右比較每一個字符時出現(xiàn)這種情況。換句話說,3 在 5 之前,所以 32 在 5 之前。
7. 排序數(shù)字
sort -t: +1 -n vegetables 此命令序列按照第二個字段對 vegetables 文件進(jìn)行數(shù)字排序。如果 vegetables 文件與示例 6 中的相同,那么 sort 命令將顯示: radishes:5 turnips:8 lettuce:15 potatoes:15 green beans:32 carrots:104 yams:104 8. 要對多個字段排序,請輸入: sort -t: +1 -2 -n +0 -1 -r vegetables 或 sort -t: -k2,2 n -k1,1 r vegetables 此命令序列對第二字段(+1 -2 -n)進(jìn)行數(shù)字排序。在這個順序中,它以逆字母順序(+0 -1 -r)對第一字段排序。將 LC_ALL、LC_COLLATE 或 LANG 環(huán)境變量設(shè)置為 C 的情況下,輸出將類似于: radishes:5 turnips:8 potatoes:15 lettuce:15 green beans:32 yams:104 carrots:104 此命令按數(shù)字順序?qū)π信判?。?dāng)兩行數(shù)字相同時,它們以逆字母順序出現(xiàn)。
9. 使用排序的文本替換原始文件
sort -o vegetables vegetables 此命令序列將排序輸出存入 vegetables 文件( -o vegetables)。 文件 /usr/bin/sort 包含 sort 命令。 /var/tmp sort 命令處理期間的臨時空間。 /usr/tmp 如果不能在 /var/tmp 中創(chuàng)建文件,是 sort 命令處理期間的臨時空間。 /tmp 如果不能在 /var/tmp 或 /usr/tmp 中創(chuàng)建文件,是 sort 命令處理期間的臨時空間。
sort 是將文件的每一行作為一個單位,相互比較,比較原則是從首字符向后,依次按照ASCII碼值進(jìn)行比較,默認(rèn)將他們按照升序輸出
降序
在輸出中去重
將排序結(jié)果輸出到原文件
sort的默認(rèn)輸出是輸出到標(biāo)準(zhǔn)輸出,如果想把結(jié)果輸出到文件,需要 sort file newfile,但是如果想把結(jié)果輸出到原文件這樣就不行了,這時就需要 使用sort -o
以數(shù)值來排序
sort 默認(rèn)是按照字符串排序的,這樣就會出現(xiàn)10比3小的情況,sort -n 就可以告訴sort 以整數(shù)排序
-t 后面跟 分隔符
-k 后面跟數(shù)字,表示用第幾列排序
如 sort -t : -k 2 表示把每行 以:號分割,按照第二列排序
banana:30:5.5
orange:20:3.4
apple:10:2.5
我們可以看到,當(dāng)baidu 和soho都是100的時候,baidu排在前面,當(dāng)當(dāng)前域按照默認(rèn)規(guī)矩,是從第一個域開始進(jìn)行升序排序,因此baidu排在了sohu前面。
sort 支持 -k 2 -k3這種模式,如果你需要,你可以繼續(xù)這么寫下去
你仔細(xì)看看,在-k 3后面偷偷加上了一個小寫字母r,r和-r的作用是一樣,你也可以把前面的-n去掉 在r后面加上n,如下
其實(shí)-k 選項 功能很強(qiáng)大,語法[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]
從逗號前后 分為兩大部分,即-k 2,2,是嚴(yán)格使用第一個域排序,如果只設(shè)置-k 2 其實(shí)是按照從第一個域到行尾。逗號分開的每部分又有一個點(diǎn)表示子域,即-k 1.2表示 按照第一個域的第二個字符排序,Modifiers就是我們用到的n和r 如 -k 1.2nr 具體我們看下面的例子。
我們使用了-k 1.2,這就表示對第一個域的第二個字符開始到本域的最后一個字符為止的字符串進(jìn)行排序。你會發(fā)現(xiàn)baidu因?yàn)榈诙€字母是a而名列榜首。sohu和 google第二個字符都是o,但sohu的h在google的o前面,所以兩者分別排在第二和第三。這和之前說到的按照默認(rèn)的排序規(guī)則 是不同的,當(dāng)?shù)谝粋€域的第二個字符相同時,他不會去按照第一個字符排序,而是按照后面的字符排序,這是因?yàn)?k 1.2是對第一個域的第二個字符開始到本域的最后一個字符為止的字符串進(jìn)行排序。而之前的夸域其實(shí)是一種假象。
-u只識別用-k設(shè)定的域,發(fā)現(xiàn)相同,就將后續(xù)相同的行都刪除
但是這時候,卻一行也沒有刪除。原來-u是會權(quán)衡所有-k選項,將都相同的才會刪除,只要其中有一級不同都不會輕易刪除的
可以用到b、d、f、i、n 或 r。
其中n和r你肯定已經(jīng)很熟悉了。
b表示忽略本域的簽到空白符號。
d表示對本域按照字典順序排序(即,只考慮空白和字母)。
f表示對本域忽略大小寫進(jìn)行排序。
i表示忽略“不可打印字符”,只針對可打印字符進(jìn)行排序。(有些ASCII就是不可打印字符,比如\a是報警,\b是退格,\n是換行,\r是回車等等)