2015-04-01 100 views
1

在bash中使用/bin/sort我發現,輸出通常是不正確的排序,當它來自彩色輸入。Bash排序命令不正確排序彩色輸出

例如,在包含以下內容的目錄:

$ ls 
dir1   (directory, printed in blue) 
dir2   (directory, printed in blue) 
dir3   (directory, printed in blue) 
afile   (file, printed in white) 
file1   (file, printed in white) 
file2   (file, printed in white) 
file3   (file, printed in white) 

我希望ls | sort排序afile,再dir1,等等。相反,我得到:

$ ls | sort 
dir2 
dir3 
dir1 
afile 
file1 
file2 
file3 

我已經試過相當sort(-d,-g,-h,-n)的一些選項無濟於事。

我已經能夠解決這個問題的唯一辦法是通過明確轉向ls關閉的色彩輸出:

$ ls --color=never | sort 
afile 
dir1 
dir2 
dir3 
file1 
file2 
file3 

但是,這感覺就像一個變通辦法,而不是解決問題的辦法。我一直認爲必須有辦法在最終輸出中保留顏色,只適用於不關閉顏色的情況(例如對於不支持顏色禁用的ls以外的命令)。

一種力如何排序以僅對打印字符(即文件和目錄名稱)起作用?我有興趣瞭解如何在事實之後徹底刪除顏色輸出(我已嘗試strings,但獲取藍色文本的顏色說明符[01;34m),並且特別關注是否可以在排序後保留顏色輸出。

+2

當輸出到管道'ls'應該是默認禁用顏色。如果沒有發生這種情況,那意味着您可能不小心使用「--color = always」啓用了顏色,而不是僅使用「--color」。 – 2015-04-01 20:04:55

+2

使用'\ ls | sort'爲'ls'禁用別名。 – Cyrus 2015-04-01 20:06:17

+0

它應該足夠使用'--color = auto',對吧?當寫入管道時,它會抑制顏色,並且您不必擺弄這些選項。 [編輯:我看到@Etan也是這麼說的。] – alexis 2015-04-01 20:07:04

回答

2

文本通過添加\x1b[...m形式的ANSI顏色序列進行着色,其中...被替換爲一個或多個用分號分隔的數字,該數字描述樣式。爲了對文本進行排序,您需要忽略整個顏色序列,這遠遠超出了標準語言環境排序規則定義的功能。

如果彩色輸出是由像ls這樣的程序生成的,它可以獨立地爲每一行着色,您可以使用sed創建一個排序鍵 - 刪除了顏色序列的行 - 然後是完全着色的行。

這是一個簡單的解決方案,要求TAB不存在於任何行中。 (此外,還要求有在任何條目不換行,但是這是需要的事實,條目是各個行,這是一個基本的前提使用sort。)

ls -U --color=always | # Sample data input 
sed 'h;s/\x1b[[0-9;]*m//g;G;s/\n/\t/' | # Insert the sort key 
sort |     # Sort the result 
cut -f2-    # Remove the sort key 

sed命令的說明:

h     Copy the line to the hold space 
s/\x1b[[0-9;]*m//g Remove all colour sequences 
G     Append a newline and the contents of the hold space 
s/\n/\t/   Change the newline to a tab 

注意:使用反斜槓比sed的模式\n其他和替換是GNU擴展,可能在其他SED實現也可以,但不是POSIX標準要求。對於Posix標準sed,您需要分別用二進制ESC和TAB替換\x1b\t

0

首先,你爲什麼需要sortls有一噸訂購選項內置?也許你可以通過閱讀ls的手冊來解決你的問題。

但是假設你確實需要不區分顏色的排序:你可以告訴sort在指定數量的字符之後開始排序,這並不是你所需要的,但它總比沒有好。我沒有ls的版本,所以我無法確認,但簡單的彩色文本通常是以五個字符的順序激活的。例如,藍色是^[[34m。那麼,告訴sort開始與第六個字符排序:

ls | sort -k 1.6 

但對於普通文件?他們可能沒有獲得彩色前綴,因此上述內容將會失敗,除非您將其過濾爲在黑色線條前添加相同數量的字符。爲了對稱,您可以簡單地添加黑色(^[[00m,使其成爲五個字符)。

ls | perl -pe '{ s/^/\e\[00m/ unless /^\e\[/ }' | sort -k 1.6