題 如何在Unix中使用“ls”時對第一個目錄進行排序,然後對文件等進行排序


我想用 ls 命令首先顯示目錄然後顯示文件。我試過了:

ls -la | sort -k 1

但是訂單錯了。


77
2018-02-16 13:13


起源


這是因為 - 來之前 d 使用時 sort - Nifle
舊時unix頭(來自GUI時代之前的那些)用於大寫其文件夾名稱並使普通文件名無資本化以自動獲得該結果。 - JRobert
有用的問題!或許是時候將接受的答案改為更簡單且不會破壞終端顏色的答案? - ippi


答案:


以下命令將首先列出目錄,第二個列出普通文件,第三個鏈接。

ls -la | grep "^d" && ls -la | grep "^-" && ls -la | grep "^l"

而且,創建一個很有意義 別號 用於此命令以保存擊鍵。

編輯:

如果您首先需要目錄,然後是第二個目錄,那麼請使用:

ls -la | grep "^d" && ls -la | grep -v "^d"


25
2018-02-16 13:36



如果文件夾中有套接字或FIFO,則此命令不會列出所有內容 - Studer
該編輯版本仍應與其他類型一起使用。第一個grep表示以“d”開頭的所有內容,第二個表示不以“d”開頭的所有內容。當然,一切都要么以d開頭,要不是,對吧? - Ry4an Brase
@Mark - 為什麼不這樣做: ls -la | grep "^d" && ls -la | grep "^-" && ls -la | grep -v -E "^d|^-|^total"? - FCTW
要使@ FCTW的命令成為OSX別名,請將其添加到〜/ .profile: alias la="ls -la | grep \"^d\" && ls -la | grep \"^-\" && ls -la | grep -E \"^d|^-\" -v | grep -v \"^total\"" - aliteralmind
我找到了一個較短的符號: ls -la|grep ^d;ls -la|grep -v ^d (報價不是必需的和替換的 && 同 ;)。另一種選擇是引入一個變量,然後對其進行評估: a="ls -la|grep ^d";eval $a;eval $a -v。當指定了更多選項時,可以避免重複 ls/grep。還有那個 ls -la --group-directories-first 選項,但最短的imo是 ls -la|sort - Steven Pribilinskiy


我喜歡* nix並喜歡看到這些回復中的創造性......

我對GNU Linux並不那麼喜歡:

alias ls='ls --color -h --group-directories-first'

鑑於我對我的linux CLI應用程序更加滿意,我傾向於在OSX上更新coreutils:

brew install coreutils
alias ls='/usr/local/bin/gls --color -h --group-directories-first'

181
2018-02-16 13:47



不幸的是,這不適用於osx終端,因為 - 選項不可用。 - MEM
再愛:這是諷刺嗎?如果是的話,我同意。 - allyourcode
Re:不適用於mac ...真的,個人雖然我通常做一個brew安裝coreutils來覆蓋我的本地用戶的mac內置。 - jonathanserafini
別名ls的目的是定義我想要在90%的時間使用的配置元素。減少擊鍵次數以實現所需的輸出。如果你曾經希望擁有原生ls輸出,你可以隨時/ bin / ls。 - jonathanserafini
@MEM如果您正在使用OS X並且喜歡使用終端,那麼您應該這樣做 brew install bash  然後,這將工作! :) - Andrew Ashbacher


對於Mac用戶 的coreutils

brew install coreutils

alias ls='ls --color -h --group-directories-first'

假設您的系統已準備就緒 自製


16
2018-06-13 17:01



gls 相當。對? - Paul Irish
是的,默認情況下。默認情況下,您也可以使用coreutils PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"。 - benesch


您有多種選擇,具體取決於您是否要按字母順序排列。

你可以試試:

ls -al | sort -k1 -r

或者,為了保持具有相同權限的文件的字母順序:

ls -al | sort -k1,1 -k9,9 -r

或者,正如eleven81所說(但這個版本列出了所有內容):

ls -la | grep“^ d”&& ls -la | grep“^ - ”&& ls -al | grep -v“^ [d | - ]”


6
2018-02-16 14:28



這是一個更好的解決方案IMO。使用幾個進程和管道進行排序而不是管道進行排序似乎有些倒退。特別是從 ls- al|sort -k1 -r 作品。缺少的只是 -r 旗。 - brice
@brice讓我困擾'排序'的是那個 ./ 和 ../ 按順序不會是前兩行。除此之外,我同意這是更有效的解決方案。 - thdoan


delerious010的 回答,我想補充一點,如果你想要舊式訂購:

LANG=C ls -la --group-directories-first

(或使用LC_ALL或LANGUAGE或LC_COLLATE設置為“C”)。

這將給出類似於:

.
..
DIR
Dir
dir
.hidden
123
UC_FILE
Uc_file
lc_file

雖然,如果我沒記錯的話,隱藏的點文件最初出現在目錄之前。


5
2018-02-16 14:56





我希望在目錄列表中看到某些內容,到目前為止,這裡的答案都不符合下面的所有要求。我對目錄列表的要求:

  1. 目錄和文件按字母順序排序
  2. 目錄列在第一位
  3. 符號鏈接(符號鏈接)按文件排序
  4. 排序不區分大小寫
  5. 排序會忽略文件名中所有前導的非字母字符
  6. 清單包括目錄的總數(不包括 ./ 和 ../),文件和鏈接
  7. 清單包括目錄和文件的總大小(磁盤使用情況)
  8. 在Linux和Windows(Git Bash shell)上列表看起來一樣 - 這是最難做到的,因為方便的選項如 --group-directories-first 不適用於Git Bash for Windows

經過多次黑客攻擊後,我終於想出了一個單行(雖然很長的行;-)),我很滿意。我已將此分配給名為'dir'的別名:

ls -dlF --color * .* | head -n2 && ls -AlF | LC_ALL=C grep "^d" | 
LC_ALL=C sort -k 9df && ls -AlF | LC_ALL=C grep "^[l-]" | 
LC_ALL=C sort -k 9df && echo -e `find -maxdepth 1 -type d ! -name . | 
wc -l` Dir\(s\) `du -hs | cut -f 1`\\t\\t`find -maxdepth 1 -type f | 
wc -l` File\(s\) `find -maxdepth 1 -type f -print0 | du -ch --files0-from=- | 
tail -n 1 | cut -f 1`\\t\\t`find -maxdepth 1 -type l | wc -l` Link\(s\)

為了使事情更容易管理,我想出了單獨的命令來輸出我喜歡的目錄列表的每個段,然後使用它們將它們組合在一起 && 運營商。

  • ls -dlF --color * .* | head -n2  - 提取 ./ 和 ../。我們不想通過這些 sort 因為它們已經處於正確的順序,並且可以對它們進行排序 ../ 被列為第一。該 -d選項是擺脫“總”線;我想補充一下 -F 顯示目錄的尾部斜杠(當你執行普通時,它也會用符號“@”標記符號鏈接 ls -F)。

  • ls -AlF | LC_ALL=C grep "^d" | LC_ALL=C sort -k 9df  - 提取目錄並按文件名排序(第9列),忽略非字母/空格字符(d 選項)和角色案例(f 選項)。該 ls -A 選項不包括在內 ./ 和 ../ 從列表開始,因為我們已經在上一步中提取了它們。我傾向於前綴所有 grep 和 sort 命令與 LC_ALL=C locale reset,以便(1)輸出在Unix shell之間保持一致,(2)你有時可以看到更快的性能,因為它不再需要處理繁重的UTF-8字符集的開銷。

  • ls -AlF | LC_ALL=C grep "^[l-]" | LC_ALL=C sort -k 9df  - 這與上面的步驟類似,但這次我們正在排序文件和符號鏈接。

  • find -maxdepth 1 -type d ! -name . | wc -l  - 獲取目錄數量,不包括 ./ 和 ../

  • find -maxdepth 1 -type f | wc -l  - 獲取文件數量。

  • find -maxdepth 1 -type l | wc -l  - 獲取符號鏈接的數量。

  • du -hs | cut -f 1  - 以人類可讀的格式提取所有子目錄的總大小。

  • find -maxdepth 1 -type f -print0 | du -ch --files0-from=- | tail -n 1 | cut -f 1  - 以人類可讀的格式提取所有文件的總大小。

讓我們看看我們的新品 dir 別名在行動!

之前:

$ ls -alF
total 22
drwxr-xr-x   13 Tom      Administ     4096 Oct 25 02:38 ./
drwxr-xr-x    3 Tom      Administ        0 Dec 24  2014 ../
drwxr-xr-x   15 Tom      Administ     4096 Sep 17 01:23 .VirtualBox/
-rw-r--r--    1 Tom      Administ      615 Oct 25 02:38 .aliases
-rw-r--r--    1 Tom      Administ    12742 Oct 24 11:47 .bash_history
-rw-r--r--    1 Tom      Administ     3234 Oct 24 15:06 .bash_profile
drwxr-xr-x    1 Tom      Administ        0 Jan 24  2015 .gem/
-rw-r--r--    1 Tom      Administ      586 Oct 24 03:53 .gitconfig
drwxr-xr-x    1 Tom      Administ     4096 Dec 28  2014 .ssh/
drwxr-xr-x    4 Tom      Administ        0 Jan 24  2015 .travis/
-rw-r--r--    1 Tom      Administ     6645 Oct 25 02:38 _viminfo
-rw-r--r--    1 Tom      Administ     4907 Oct 24 15:16 profile
drwxr-xr-x    1 Tom      Administ        0 Oct 24 22:20 tmp/

後:

$ dir
drwxr-xr-x   13 Tom      Administ     4096 Oct 25 02:38 ./
drwxr-xr-x    3 Tom      Administ        0 Dec 24  2014 ../
drwxr-xr-x    1 Tom      Administ        0 Jan 24  2015 .gem/
drwxr-xr-x    1 Tom      Administ     4096 Dec 28  2014 .ssh/
drwxr-xr-x    1 Tom      Administ        0 Oct 24 22:20 tmp/
drwxr-xr-x    4 Tom      Administ        0 Jan 24  2015 .travis/
drwxr-xr-x   15 Tom      Administ     4096 Sep 17 01:23 .VirtualBox/
-rw-r--r--    1 Tom      Administ      615 Oct 25 02:38 .aliases
-rw-r--r--    1 Tom      Administ    12742 Oct 24 11:47 .bash_history
-rw-r--r--    1 Tom      Administ     3234 Oct 24 15:06 .bash_profile
-rw-r--r--    1 Tom      Administ      586 Oct 24 03:53 .gitconfig
-rw-r--r--    1 Tom      Administ     4907 Oct 24 15:16 profile
-rw-r--r--    1 Tom      Administ     6645 Oct 25 02:38 _viminfo
      5 Dir(s) 2.8M           6 File(s) 31K           0 Link(s)

一個小的缺點是你不能有彩色列表,因為文件名周圍的顏色控製字符使得排序太不可靠。


UPDATE

從深層文件系統的根目錄執行時,上面的別名非常慢,所以我更新了這個更簡單但更高效的命令:

ls -AFoqv --color --group-directories-first | tail -n +2 && find -maxdepth 1 -type f -printf '%s\n' | awk '{total+=$1} END {print total" bytes"}'

樣本輸出:

$ dir
drwxr-xr-x 1 Tom     0 Mar 29 13:49 .aws/
drwxr-xr-x 1 Tom     0 Mar 29 13:49 .gem/
drwxr-xr-x 1 Tom     0 Mar 29 19:32 .ssh/
drwxr-xr-x 1 Tom     0 Mar 29 13:49 .zbstudio/
drwxr-xr-x 1 Tom     0 Jun 16  2016 temp/
drwxr-xr-x 1 Tom     0 Jul 13  2016 vimfiles/
-rw-r--r-- 2 Tom   365 Mar 30 10:37 .aliases
-rw-r--r-- 1 Tom 16028 Mar 30 12:12 .bash_history
-rw-r--r-- 2 Tom  2807 Mar 30 12:12 .bash_profile
-rw-r--r-- 2 Tom  2177 Mar 29 23:24 .functions
-rw-r--r-- 1 Tom  1091 Mar 30 10:34 .gitconfig
-rw-r--r-- 1 Tom  8907 Mar 29 14:45 _viminfo
-rw-r--r-- 1 Tom  2444 Jul 13  2016 _vimrc
33819 bytes

由於新版本的Git Bash for Windows支持 --group-directories-first,我們不再需要依靠 sort。即使新別名沒有顯示與先前別名一樣多的信息,但性能提升還是值得的。作為一個振作,你也獲得了顏色!


4
2017-10-24 20:07



很棒的答案!但是,當你說, “經過多次黑客攻擊,我終於想出了一個單行......” 是的,確實這不是傳統意義上的“一線”。採用該邏輯並使其成為獨立的shell腳本並運行該腳本或將其稱為別名可能是有意義的。 - JakeGould
@JakeGould你很快!我還沒有完成校對,我的答案還沒有完成,你已經讀完了它並拍了一條評論:)。是的,它是函數的主要候選者,但我當時太懶了,所以只需將它扔進我的.bash_aliases文件中。另一方面,我通常只在沒有傳遞參數的情況下無法做某事時才編寫函數。 - thdoan
@ 10basetom:快速問題:如何在ls中獲得不同顏色的列?我可以上色 文件名 通過文件類型使用ls --color,但我沒有看到一種方法來獲得列的有用顏色。秘訣是什麼? - Pirx
@Pirx我相信這些列是由默認的Stack Exchange語法突出顯示的:-)。 - thdoan
是的,這似乎是這種情況,但這是一個好主意,解決方案在;-) - Pirx


這是一個執行此操作的函數(bash或zsh): 並且...我並不是說這是最好的方式,但它是我想出的並且現在正在使用的方式:

功能lss
{
    #顯示目錄列表,頂部有目錄。

    命令ls --color =總是$ @ | egrep'^ d | total'
    命令ls --color =總是$ @ | egrep -v'^ d | total';
}

2
2018-02-16 13:37



只是一個fyi這似乎不起作用。你需要使用長列表格式(ls -l)為了按照那樣的文件類型進行過濾。此外,此命令將在空格(在bash中)中斷。你需要這樣引用: "$@" 如果你想使用這種方法,你可以這樣做: function lss {local temp="$(command ls -l --color=always "$@")"; egrep --color=never '^d|total' <<<"$temp"; egrep --color=never -v '^d|total' <<<"$temp"} - Six