sort 命令常用於字段排序。
用法:sort [選項]... [文件]... 或:sort [選項]... --files0-from=F 串聯排序所有指定文件並將結果寫到標准輸出。 長選項必須使用的參數對於短選項時也是必需使用的。 排序選項: -b, --ignore-leading-blanks 忽略前導的空白區域 -d, --dictionary-order 只考慮空白區域和字母字符 -f, --ignore-case 忽略字母大小寫 -g, --general-numeric-sort 按照常規數值排序 -i, --ignore-nonprinting 只排序可打印字符 -M, --month-sort 比較 (未知) < "一月" < ... < "十二月" 在LC_ALL=C 時為(unknown) < `JAN' < ... < `DEC' -h, --human-numeric-sort 使用易讀性數字(例如: 2K 1G) -n, --numeric-sort 根據字符串數值比較 -R, --random-sort 根據隨機hash 排序 --random-source=文件 從指定文件中獲得隨機字節 -r, --reverse 逆序輸出排序結果 --sort=WORD 按照WORD 指定的格式排序: 一般數字-g,高可讀性-h,月份-M,數字-n, 隨機-R,版本-V -V, --version-sort 在文本內進行自然版本排序 其他選項: --batch-size=NMERGE 一次最多合並NMERGE 個輸入;如果輸入更多 則使用臨時文件 -c, --check, --check=diagnose-first 檢查輸入是否已排序,若已有序則不進行操作 -C, --check=quiet, --check=silent 類似-c,但不報告第一個無序行 --compress-program=程序 使用指定程序壓縮臨時文件;使用該程序 的-d 參數解壓縮文件 --files0-from=文件 從指定文件讀取以NUL 終止的名稱,如果該文件被 指定為"-"則從標准輸入讀文件名 -k, --key=位置1[,位置2] 在位置1 開始一個key,在位置2 終止(默認為行尾) -m, --merge 合並已排序的文件,不再進行排序 -o, --output=文件 將結果寫入到文件而非標准輸出 -s, --stable 禁用last-resort 比較以穩定比較算法 -S, --buffer-size=大小 指定主內存緩存大小 -t, --field-separator=分隔符 使用指定的分隔符代替非空格到空格的轉換 -T, --temporary-directory=目錄 使用指定目錄而非$TMPDIR 或/tmp 作為 臨時目錄,可用多個選項指定多個目錄 -u, --unique 配合-c,嚴格校驗排序;不配合-c,則只輸出一次排序結果 -z, --zero-terminated 以0 字節而非新行作為行尾標志 --help 顯示此幫助信息並退出 --version 顯示版本信息並退出 POS 是F[.C][OPTS],F 代表域編號,C 是域中字母的位置,F 和C 均從1開始計數 如果沒有有效的-t 或-b 選項存在,則從前導空格後開始計數字符。OPTS 是一個或多個 由單個字母表示的順序選項,以此覆蓋此key 的全局順序設置。如果沒有指定key 則 將其整個行。 指定的大小可以使用以下單位之一: 內存使用率% 1%,b 1、K 1024 (默認),M、G、T、P、E、Z、Y 等依此類推。 如果不指定文件,或者文件為"-",則從標准輸入讀取數據。
比較原則是從首字符開始,依次按ASCII碼值進行比較,最後將比較結果按升序輸出。
創建一個測試文件 test.txt,內容:
6d7fce9fee471194aa8b5b6e47267f03 ./version.ini 8c47b68c23994cf382bd12a3bd4a1fe8 ./plugin.conf e45f64ed552ab0176be337ad77f3b3ae ./start.sh 6172fad14869bbb949ea1d60c4771f14 ./stop.sh 8dd2db4b88727758bb0800c321bafc34 ./test_proc 1e142f0d573c5891cc14d8864e073d53 ./test_proc.c
# sort test.txt 1e142f0d573c5891cc14d8864e073d53 ./test_proc.c 6172fad14869bbb949ea1d60c4771f14 ./stop.sh 6d7fce9fee471194aa8b5b6e47267f03 ./version.ini 8c47b68c23994cf382bd12a3bd4a1fe8 ./plugin.conf 8dd2db4b88727758bb0800c321bafc34 ./test_proc e45f64ed552ab0176be337ad77f3b3ae ./start.sh
# sort -k 2 -t "." test.txt 8c47b68c23994cf382bd12a3bd4a1fe8 ./plugin.conf e45f64ed552ab0176be337ad77f3b3ae ./start.sh 6172fad14869bbb949ea1d60c4771f14 ./stop.sh 8dd2db4b88727758bb0800c321bafc34 ./test_proc 1e142f0d573c5891cc14d8864e073d53 ./test_proc.c 6d7fce9fee471194aa8b5b6e47267f03 ./version.ini
sort -k 2 -t "." test.txt,根據符號“.”分割字符串,並以 分割後的test.txt 文件中的第2列進行排序。
10比2用 sort 命令排序的時候,可能會出現10比較小的情況。這是因為排序程序將數字按字符來排序,排序程序會先比較1和2,顯然1小,所以就將10放在2前面。這也是sort的一貫作風。 如果要改變這種排序方式,就要使用-n選項,指定以數值來排序。
sort默認的排序方式是升序,如果想改成降序
]# sort -r -k 2 -t "." test.txt 6d7fce9fee471194aa8b5b6e47267f03 ./version.ini 1e142f0d573c5891cc14d8864e073d53 ./test_proc.c 8dd2db4b88727758bb0800c321bafc34 ./test_proc 6172fad14869bbb949ea1d60c4771f14 ./stop.sh e45f64ed552ab0176be337ad77f3b3ae ./start.sh 8c47b68c23994cf382bd12a3bd4a1fe8 ./plugin.conf
# sort -r -k 2 -t "." test.txt -o test.txt # cat test.txt 6d7fce9fee471194aa8b5b6e47267f03 ./version.ini 1e142f0d573c5891cc14d8864e073d53 ./test_proc.c 8dd2db4b88727758bb0800c321bafc34 ./test_proc 6172fad14869bbb949ea1d60c4771f14 ./stop.sh e45f64ed552ab0176be337ad77f3b3ae ./start.sh 8c47b68c23994cf382bd12a3bd4a1fe8 ./plugin.conf
將小寫字母都轉換為大寫字母來進行比較,即忽略大小寫
在一個項目中,有過類似的經歷:使用 php 的 exec() 函數執行命令:sort -k 2 -t"." 結果是:
6d7fce9fee471194aa8b5b6e47267f03 ./VERSION.ini 8c47b68c23994cf382bd12a3bd4a1fe8 ./plugin.conf e45f64ed552ab0176be337ad77f3b3ae ./start.sh 6172fad14869bbb949ea1d60c4771f14 ./stop.sh 8dd2db4b88727758bb0800c321bafc34 ./test_proc 1e142f0d573c5891cc14d8864e073d53 ./test_proc.c
# sort -f -k 2 -t"." test.txt 8c47b68c23994cf382bd12a3bd4a1fe8 ./plugin.conf e45f64ed552ab0176be337ad77f3b3ae ./start.sh 6172fad14869bbb949ea1d60c4771f14 ./stop.sh 8dd2db4b88727758bb0800c321bafc34 ./test_proc 1e142f0d573c5891cc14d8864e073d53 ./test_proc.c 6d7fce9fee471194aa8b5b6e47267f03 ./VERSION.ini
解決方法可以在php 中,使用 exec() 函數執行命令:sort -f -k 2 -t"." 。
繼續探討上面的問題,懷疑是跟本地環境變量或者編碼存在關系,測試一下:
~$ locale LANG=en_US.UTF-8 LANGUAGE=en_US: LC_CTYPE="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_COLLATE="en_US.UTF-8" LC_MONETARY="en_US.UTF-8" LC_MESSAGES="en_US.UTF-8" LC_PAPER="en_US.UTF-8" LC_NAME="en_US.UTF-8" LC_ADDRESS="en_US.UTF-8" LC_TELEPHONE="en_US.UTF-8" LC_MEASUREMENT="en_US.UTF-8" LC_IDENTIFICATION="en_US.UTF-8" LC_ALL=
~$ sort -k 2 -t"." test.txt 8c47b68c23994cf382bd12a3bd4a1fe8 ./plugin.conf e45f64ed552ab0176be337ad77f3b3ae ./start.sh 6172fad14869bbb949ea1d60c4771f14 ./stop.sh 8dd2db4b88727758bb0800c321bafc34 ./test_proc 1e142f0d573c5891cc14d8864e073d53 ./test_proc.c 6d7fce9fee471194aa8b5b6e47267f03 ./VERSION.ini
~$ export LC_ALL=zh_CN.UTF-8 :~$ locale LANG=en_US.UTF-8 LANGUAGE=en_US: LC_CTYPE="zh_CN.UTF-8" LC_NUMERIC="zh_CN.UTF-8" LC_TIME="zh_CN.UTF-8" LC_COLLATE="zh_CN.UTF-8" LC_MONETARY="zh_CN.UTF-8" LC_MESSAGES="zh_CN.UTF-8" LC_PAPER="zh_CN.UTF-8" LC_NAME="zh_CN.UTF-8" LC_ADDRESS="zh_CN.UTF-8" LC_TELEPHONE="zh_CN.UTF-8" LC_MEASUREMENT="zh_CN.UTF-8" LC_IDENTIFICATION="zh_CN.UTF-8" LC_ALL=zh_CN.UTF-8 ~$ sort -k 2 -t"." test.txt 6d7fce9fee471194aa8b5b6e47267f03 ./VERSION.ini 8c47b68c23994cf382bd12a3bd4a1fe8 ./plugin.conf e45f64ed552ab0176be337ad77f3b3ae ./start.sh 6172fad14869bbb949ea1d60c4771f14 ./stop.sh 8dd2db4b88727758bb0800c321bafc34 ./test_proc 1e142f0d573c5891cc14d8864e073d53 ./test_proc.c
使用-r選項例子中執行後的文件
# cat test.txt 6d7fce9fee471194aa8b5b6e47267f03 ./version.ini 1e142f0d573c5891cc14d8864e073d53 ./test_proc.c 8dd2db4b88727758bb0800c321bafc34 ./test_proc 6172fad14869bbb949ea1d60c4771f14 ./stop.sh e45f64ed552ab0176be337ad77f3b3ae ./start.sh 8c47b68c23994cf382bd12a3bd4a1fe8 ./plugin.conf
# sort -c test.txt sort:test.txt:2:無序: 1e142f0d573c5891cc14d8864e073d53 ./test_proc.c
檢查文件是否已排好序,如果是亂序則不輸出內容,僅是返回1