每个子目录中的文件数


22

我想要一个BASH命令来仅列出目录的每个子目录中的文件计数。

例如,在目录中/tmp都存在dir1dir2......我想看看:

`dir1` : x files 
`dir2` : x files ...

Answers:


33

假设您只想递归计数文件,而不是目录和其他类型,则应如下所示:

find . -maxdepth 1 -mindepth 1 -type d | while read dir; do
  printf "%-25.25s : " "$dir"
  find "$dir" -type f | wc -l
done

另外,我得到“发现:警告:您在非选项参数-type之后指定了-maxdepth选项,但是选项不是位置性的(-maxdepth影响在其之前指定的测试以及在其之后指定的测试)。请指定选项在其他论点之前。”
jldupont 2012年

2
到目前为止给出的两个答案都将在某些情况下(文件名中包含换行符)给出错误的结果。您可以通过find... -print0 | xargs -0....
Scott

@jldupont:将深度参数移到“ -d型”之前,我已经编辑了答案。
2012年

是的,让我补充一下信息,这个出色的解决方案不会采用任何外部变量,因此可以使用bash alias!!
语法错误

快,并sort -rn -k 2,2 -t$':'得到管道的DESC列表
Andre Figueiredo

14

这项任务使我着迷,以至于我想自己想办法。它甚至不需要一段时间的循环,并且执行速度可能更快。不用说,Thor的努力对我详细了解了很多东西。

所以这是我的:

find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "{} : $(find "{}" -type f | wc -l)" file\(s\)' \;

它看起来适中是有原因的,因为它的功能比看起来更强大。:-)

但是,如果您打算将此包含到.bash_aliases文件中,则它必须如下所示:

alias somealias='find . -maxdepth 1 -mindepth 1 -type d -exec sh -c '\''echo "{} : $(find "{}" -type f | wc -l)" file\(s\)'\'' \;'

请注意嵌套引号的非常棘手的处理。不,参数不能使用双引号sh -c


由于它为每个目录调用/ bin / sh,所以速度较慢。您可以使用进行检查strace -fc script。您的版本发出了大约70%的系统调用。+1代表更短的代码:-)
雷神

1
受此启发;按文件数排序:find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "$(find "{}" -type f | wc -l)" {}' \; | sort -nr
mnagel

7
find . -type f | cut -d"/" -f2 | uniq -c

列出当前文件夹中的文件夹和文件,并在下面找到文件数量。快速实用的IMO。(文件显示为1)。


1
关于它如何工作的一些解释呢?:)
C0deDaedalus

1
很好,谢谢!您可能需要添加| sort -rn按文件数排序子目录。
丹尼斯·戈洛马佐夫

1

如果要递归计数,则使用find绝对是一种方法,但是如果您只想直接在某个目录下计数文件:

ls dir1 | wc -l


我不想为我在那里的1000个目录中的每个目录执行此操作...
jldupont 2012年

然后使用xargs。ls -d */ | xargs -n1 ls | wc -l(不过,使用您接受的答案,如果它已经有效的话!这只是现在就知道。)
jrajav 2012年

您的提案在很多秒内没有显示任何结果,而我接受的答案却没有。
jldupont 2012年

@jrajav对于包含空格的目录,此方法绝对会失败。这就是为什么find如此重要的原因。(更不用说-print0xargs -0,已经由Scott在对方的回答中指出)
的SyntaxError

1
find . -mindepth 1 -type d -print0 | xargs -0 -I{} sh -c 'printf "%4d : %s\n" "$(find {} -type f | wc -l)" "{}"'

我经常需要计算子目录中的文件数并使用此命令。我希望计数首先出现。


0

我用的...这将在您作为参数给出的所有子目录中组成一个数组。打印子目录和相同子目录的计数,直到处理完所有子目录。

#!/bin/bash    
directories=($(/bin/ls -l $1 | /bin/grep "^d" | /usr/bin/awk -F" " '{print $9}'))

for item in ${directories[*]}
    do
        if [ -d "$1$item" ]; then
            echo "$1$item"
            /bin/ls $1$item | /usr/bin/wc -l
        fi
    done

0

您可以使用此python代码。通过运行启动解释器python3并粘贴以下内容:

folder_path = '.'
import os, glob
for folder in sorted(glob.glob('{}/*'.format(folder_path))):
    print('{:}: {:>8,}'.format(os.path.split(folder)[-1], len(glob.glob('{}/*'.format(folder)))))

或嵌套计数的递归版本:

import os, glob
def nested_count(folder_path, level=0):
    for folder in sorted(glob.glob('{}/'.format(os.path.join(folder_path, '*')))):
        print('{:}{:}: {:,}'.format('    '*level, os.path.split(os.path.split(folder)[-2])[-1], len(glob.glob(os.path.join(folder, '*')))))
        nested_count(folder, level+1)
nested_count('.')

输出示例:

>>> figures: 5
>>> misc: 1
>>> notebooks: 5
>>>     archive: 65
>>>     html: 12
>>>     py: 12
>>>     src: 14
>>> reports: 1
>>>     content: 6
>>> src: 1
>>>     html_download: 1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.