[英]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}
D
( glob_dots
)包括名稱以句點開頭的文件, N
( null_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.