2009-11-05 78 views
7

我經常使用Bash中的優秀find程序列出帶有某些過濾器的文件。例如,在一個Subversion(SVN)的工作拷貝,有時我真希望遞歸列出所有文件,但不包括.svn子目錄如下:Bash命令遞歸列出文件,但按分類排序

find . -name '.svn' -prune -o -type f -print 

今天,我想要做類似的事情,但我也想影響列出了目錄內容的順序:我希望「普通」文件後跟子目錄(然後是遞歸內容)。這似乎沒有選擇。

ls(list)命令有一個遞歸列表選項。此命令有許多排序選項,包括按文件名列出,訪問時間,大小等,但不分類,但-p選項將註釋目錄。

現在,我可能會寫,例如,一個Python腳本來完成我想要的。但是,find已經做了幾乎所有我想要的。通常在Bash shell中,可以將程序合併爲你想要的:每個程序(如find,sort,uniq,ls,wc)執行一個簡單的任務,但是做得很好。並非每個程序都需要進行排序,因爲sort可以排序。所以,真的,我只是好奇......

我的問題是,你知道是否有一種方法可以做我想做的事情:只需組合Bash程序來篩選和排序遞歸文件列表?

例如,find給我的文件在此,字母,次序:

a.txt 
b\file1.txt 
b\subdir\file2.txt 
b\then_file3.txt 
c.txt 
d\file4.txt 
e.txt 

,但我寧願他們在這個順序,其中每個目錄中,普通的文件按字母順序排列第一,其次是目錄,再按照字母順序:

a.txt 
c.txt 
e.txt 
b\file1.txt 
b\then_file3.txt 
b\subdir\file2.txt 
d\file4.txt 

(我是Windows用戶,但我在Cygwin運行的Bash shell)

謝謝。

回答

10

使用嵌入式查找。外find找到的所有目錄和執行內部發現這表明只是你想要在該目錄中的文件:

find . -type d -exec find {} -type f -maxdepth 1 \; 
+1

這有效,但會發出警告。他們可能被'-nowarn'選項關閉。 – 2009-11-05 23:28:13

+0

謝謝!我認爲這可能會以某種方式。 那麼,我的SVN過濾示例就是 找不到。 -name'.svn'-prune -o -type d -exec find {} -type f -nowarn -maxdepth 1 \; – Rhubbarb 2009-11-06 00:08:24

+1

當我嘗試這樣做時,結果未排序(由dir和dir級別內)。 – 2009-11-06 01:28:30

1
tree -fi 

在Ubuntu和CentOS(和Red Hat,Fedora的...),它包含在其自己的包,叫做「樹」(杜)。默認情況下,Ubuntu似乎不安裝該軟件包,其他人則默認安裝該軟件包。

編輯:對不起,沒有意識到你正在使用Cygwin。那麼,它也被移植到Cygwin。如果它不在默認設置中,see here

+0

您也可以添加'-a'來獲取隱藏文件。 – 2009-11-06 01:18:58

0

如果目錄的深度超過一個級別,您沒有說明您想要如何處理這些事情。像這樣的事情做你想要的東西嗎?它廣度優先上市,每個深度級別內排序:

$for ((l = 0; l <= 24; l++)); do find . -mindepth ${l} -maxdepth ${l} -type f | sort; done 
+0

這很難表達,所以我試圖在例子中說明這一點。我*不*想要所有文件,然後所有目錄(這很容易)。 雖然在給定的目錄下,我希望首先列出文件,然後處理每個子目錄,然後依次遞歸到每個子目錄中。 – Rhubbarb 2009-11-06 00:02:11

2

這組首先將每個等級內的目錄,然後將文件和遞歸進入每個級別不相同:

ls -lR --group-directories-first 

儘管如此,它與你想要的相反。