簡體   English   中英

查找目錄中的文件數

[英]Find the number of files in a directory

Linux中是否有任何方法可以計算O(1)中目錄(即直接子節點)中的文件數(與文件數無關),而無需先列出目錄? 如果不是O(1),是否有合理有效的方法?

我正在尋找ls | wc -l的替代品 ls | wc -l

readdir並不像你想象的那么昂貴。 訣竅是避免統計每個文件,並(可選)對ls的輸出進行排序。

/bin/ls -1U | wc -l

避免shell中的別名,不對輸出進行排序,並列出每行1個文件(在將輸出匯總到wc時不是絕對必要的)。

原始問題可以改為“目錄的數據結構是否存儲條目數的計數?”,答案為否。 沒有比readdir(2)/ getdents(2)更有效的文件計數方法。

通過stat'ing(stat(1)或stat(2))給定目錄並觀察到該目錄的鏈接數,可以獲得給定目錄的子目錄數而不遍歷整個列表。 具有N個子目錄的給定目錄將具有N + 2的鏈接計數,每個子目錄的“...”條目的一個鏈接,以及“。”的兩個鏈接。 和給定目錄的“..”條目。

但是,如果沒有遍歷整個列表,則無法獲取所有文件的數量(無論是常規文件還是子目錄) - 這是正確的。

但是,“/ bin / ls -1U”命令不會獲得所有條目。 這將得到不以點(。)字符開頭的目錄條目。 例如,它不會計算許多登錄$ HOME目錄中的“.profile”文件。

可以使用“/ bin / ls -f”命令或“/ bin / ls -Ua”命令來避免排序並獲取所有條目。

或許不幸的是,“/ bin / ls -f”命令或“/ bin / ls -Ua”命令也會計算“。”。 和每個目錄中的“..”條目。 您必須從計數中減去2以避免計算這兩個條目,例如以下內容:

expr `/bin/ls -f | wc -l` - 2     # Those are back ticks, not single quotes.

在管道“ls”輸出時,“/ bin / ls -Ua”命令中不需要--format =單列(-1)選項,在本例中為“wc”。 如果輸出不是終端,“ls”命令將自動將其輸出寫入單個列。

-U的選項ls是不是在POSIX,而在OS X的ls它已經從GNU不同的意義ls ,這是它使-t-l使用創建時間,而不是修改時間。 -f在POSIX中作為XSI擴展。 GNU ls的手冊描述了-f as as do not sort, enable -aU, disable -ls --color-U as as do not sort; list entries in directory order do not sort; list entries in directory order

POSIX描述-f像這樣:

強制將每個參數解釋為目錄,並列出每個插槽中找到的名稱。 該選項應關閉-l-t-s-r ,並打開-a ; 順序是條目在目錄中出現的順序。

當文件名包含換行符時, ls|wc -l等命令會給出錯誤的結果。

在zsh中你可以這樣做:

a=(*(DN));echo ${#a}

Dglob_dots )包括名稱以句點開頭的文件, Nnull_glob )導致該命令不會導致空目錄中的錯誤。

或者在bash中也是如此:

shopt -s dotglob nullglob;a=(*);echo ${#a[@]}

如果IFS包含ASCII數字,請在${#a[@]}周圍添加雙引號。 添加shopt -u failglob以確保failglob設置failglob

便攜式選項是使用find

find . ! -name . -prune|grep -c /

如果文件名不包含換行符,則可以用wc -l替換grep -c / ! -name . -prune ! -name . -prune-mindepth 1 -maxdepth 1的便攜式替代品。

或者這是另一種通常不包含名稱以句點開頭的文件的替代方案:

set -- *;[ -e "$1" ]&&echo "$#"

但是,上面的命令包含的文件的名稱以一個句點開頭,當時設置了bash中的dotglob或zsh中的glob_dots *匹配no file時,該命令會在zsh中使用默認設置導致錯誤。

我使用這個命令..像一個魅力..只是改變maxdepth ..這是子目錄

find * -maxdepth 0 -type d -exec sh -c "echo -n {} ' ' ; ls -lR {} | wc -l" \;

我認為你可以使用find更多地控制它:

find <path> -maxdepth 1 -type f -printf "." | wc -c
  • find -maxdepth 1不會深入到文件的層次結構中。
  • -type f允許過濾到文件。 同樣,您可以將-type d用於目錄。
  • -printf "." 為每場比賽打印一個點。
  • wc -c對字符進行計數,因此它計算print創建的點數...這意味着計算給定路徑中存在的文件數量。

據我所知,沒有更好的選擇。 這個信息可能與這個問題有關,你可能已經知道在Linux下(一般在Unix下)目錄只是包含其他文件列表的特殊文件(我知道具體細節將取決於特定文件)系統,但這是一般的想法)。 並且沒有調用來查找沒有遍歷整個列表的條目總數。 如果我錯了,請讓我糾正。

對於當前目錄中所有文件的數量,請嘗試以下操作:

ls -lR * | wc -l

使用ls -1 | wc -l

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM