递归计数Linux目录中的文件


728

如何递归计算Linux目录中的文件?

我找到了这个:

find DIR_NAME -type f ¦ wc -l

但是,当我运行它时,它返回以下错误。

find:路径必须在表达式之前:¦


64
您会把折线¦(ASCII 166)与|用于UNIX管道的竖线(ASCII 124)混淆。
Skippy le Grand Gourou 2014年

7
@SkippyleGrandGourou不是叫烟斗吗?
DaveStephens 2015年

27
@DaveStephens是的,它也被称为。也称为Sheffer笔划,垂直杆,vbar,杆,垂直线,垂直斜线,杆,方尖碑,滑石。
emlai 2015年

64
@zenith我只是称其为Bob。
克里斯托弗·

15
在RFC20中,它称为“垂直线”。“管道”是shell运算符的名称,而不是符号的名称。就像*“星号” ASCII字符一样,但是在其他一些上下文中则是“时间”。
苗条的

Answers:


1325

这应该工作:

find DIR_NAME -type f | wc -l

说明:

  • -type f 仅包含文件。
  • |而不是¦)将find命令的标准输出重定向到wc命令的标准输入。
  • wc(字数计数的缩写)在其输入(docs)上计算换行符,单词和字节。
  • -l 仅计算换行符。

笔记:

  • 替换DIR_NAME.在当前文件夹要执行的命令。
  • 您也可以删除 -type f以在计数中包含目录(和符号链接)。
  • 如果文件名可以包含换行符,则此命令可能会计数过多。

您的示例为何无效的说明:

在显示的命令中,您并没有使用“管道”(|)来连接两个命令,而是用断线(¦)将外壳识别为命令或类似内容。这就是为什么您收到该错误消息的原因。


26
f-type f代表文件和wc -l词数线。
Serge Stroobandt

3
删除-type f要包括目录在内的目录
phatblat

3
没有必要为-print标志
佐尔坦

3
如果文件名中可能包含换行符,则可能要使用该-print0标志。
gaboroncancio 2014年

2
@gaboroncancio这将无济于事,除非的某些实现wc具有读取空终止列表的选项。请参阅我的答案。
恢复莫妮卡请


69

如果要细分当前目录下每个目录中有多少个文件,请执行以下操作:

for i in */ .*/ ; do 
    echo -n $i": " ; 
    (find "$i" -type f | wc -l) ; 
done

当然,这可以全线进行。括号明确了wc -l应该监视其输出(find $i -type f在这种情况下)。


7
它可能卡在名称中带有空格的目录上。更改第一行即可find . -maxdepth 1 -type d -print0 | while IFS= read -r -d '' i ; do解决。请参阅如何逐行(和/或逐字段)读取文件(数据流,变量)?
斯坦顿拱门[

4
使用find的外环只是一个不必要的并发症。for i in */; 做`
Tripleee

函数countit {for i in $(find。-maxdepth 1 -type d); 做file_count = $(找到$ i -type f | wc -l); 回声“ $ file_count:$ i”; 完成}; 县| sort -n -r
Schneems

最后,这就是我所需要的。我的文件夹中有成千上万个文件,因此无法用树或其他任何方式打印它们
lesolorzanov

这包括../,并且似乎没有前进的趋势-这意味着它不是回归的。
Daniel Lefebvre

50

您可以使用

$ tree

在安装包之后

$ sudo apt-get install tree

(在Debian / Mint / Ubuntu Linux机器上)。

该命令不仅分别显示文件数,而且还显示目录数。选项-L可用于指定最大显示级别(默认情况下,该级别是目录树的最大深度)。

通过提供-a选项,也可以包含隐藏文件。


4
实际上,这是查看目录和文件数量的最简单方法。
Lorem Ipsum Dolor

11
从手册页:默认情况下,tree不打印隐藏文件。您必须提供-a包括它们的选项。
eee

3
要将其安装在macOS上,请使用brew并运行brew install tree,最好先运行brew update
Ashish Ahuja,

4
它还会打印所有文件名,因此如果您有很多文件,它将很慢。
Franck Dernoncourt

2
哇,非常不错的工具,它可以打印彩色文件夹,仅列出文件夹,并以JSON输出。它可以在几秒钟内列出34k文件夹和51k文件。哦!
brasofilo

46

在我的计算机上,rsyncfind | wc -l接受的答案要快一点:

$ rsync --stats --dry-run -ax /path/to/dir /tmp

Number of files: 173076
Number of files transferred: 150481
Total file size: 8414946241 bytes
Total transferred file size: 8414932602 bytes

第二行具有文件数,在上面的示例中为150481。作为奖励,您还可以获得总大小(以字节为单位)。

备注:

  • 第一行是文件,目录,符号链接等的总计数,这就是为什么它比第二行大的原因。
  • --dry-run(或-n简称)选项没有实际传输文件是很重要的!
  • 我使用了-x“不越过文件系统边界” 的选项,这意味着如果执行该选项/并且连接了外部硬盘,它将仅计算根分区上的文件。

我喜欢您在这里使用rsync的想法。我从来没有想过!
Qeole '16

谢谢@Qeole,但是这个想法不是我的。几年前,我读过某本书,其中rsync是删除包含大量文件和子文件夹的文件夹最快的方法,因此我认为对文件进行计数也可能很快。
psmith

1
试过这个。在两次都运行两次以填充fs高速缓存后,find ~ -type f | wc -l花费了1.7 / 0.5 / 1.33秒(真实/用户/ sys)。rsync --stats --dry-run -ax ~ /xxx花了4.4 / 3.1 / 2.1秒。固态硬盘上大约有500,000个文件。
苗条的

Dunno您使用了什么版本的rsync,但在3.1.2中Number of files: 487 (reg: 295, dir: 192)
则更

我在macOS上使用了默认的rsync:rsync version 2.6.9 protocol version 29
psmith

20

由于UNIX中的文件名可能包含换行符(是,换行符),因此wc -l文件数可能过多。我会为每个文件打印一个点,然后计算点数:

find DIR_NAME -type f -printf "." | wc -c

1
看起来这是处理名称中带有换行符的文件的唯一解决方案。已投票。
codeforester

2
hihi :)我喜欢文件名中的换行符。这使得它们更具可读性。
hek2mgl

我的意思是,文件名中的换行符不是内容!
codeforester

1
我只是在开玩笑...是的,始终必须考虑文件名中的换行符。它们可能来自恶意内容,也可能来自错别字。
hek2mgl

18

结合这里的几个答案,最有用的解决方案似乎是:

find . -maxdepth 1 -type d -print0 |
xargs -0 -I {} sh -c 'echo -e $(find "{}" -printf "\n" | wc -l) "{}"' |
sort -n

它可以处理一些奇怪的事情,例如文件名中包含空格括号甚至是换行符。它还按文件数对输出进行排序。

您也可以在增加-maxdepth子目录之后增加数量。请记住,这可能会花费很长时间,尤其是当您具有高度嵌套的目录结构和-maxdepth大量的目录结构时。


是什么echo -e?我猜您将其放在可以折叠任何换行符的位置,但是它也会破坏任何其他不规则的空格,并尝试扩展文件名中逐字出现的通配符。我可以简单地处理类似的内容,find .* * -type d -execdir sh -c 'find . -type f -printf "\n" | wc -l; pwd'并在输出中包含任何异常,或者可以使用Bash printf "%q"来打印目录名称。
Tripleee

10

如果您想知道当前工作目录中存在多少个文件和子目录,可以使用这种单行代码

find . -maxdepth 1 -type d -print0 | xargs -0 -I {} sh -c 'echo -e $(find {} | wc -l) {}' | sort -n

这将以GNU风格工作,并且仅在BSD linux(例如OSX)的echo命令中省略-e。


2
优秀的解决方案!我发现的唯一问题是带有空格或特殊字符的目录。在使用目录名称的地方添加引号:find . -maxdepth 1 -type d -print0 | xargs -0 -I {} sh -c 'echo -e $(find "{}" | wc -l) "{}"' | sort -n
John Kary

1
我对其进行了一些修改,对我来说效果很好:find . -maxdepth 1 -type d -print0 | xargs -0 -I {} sh -c 'echo $(find {} | wc -l) \\t {}' | sort -rn | less
Wizek

我对@Sebastian答案的评论也适用于此。echo -e在未加引号的目录名称上使用(或仅在前面的注释中使用`echo`)将一个问题换成另一个问题。
Tripleee

8

如果要避免出现错误情况,请不要允许 wc -l查看带有换行符的文件(它将被视为2个以上的文件)

例如,考虑一种情况,我们只有一个文件,其中包含一个EOL字符

> mkdir emptydir && cd emptydir
> touch $'file with EOL(\n) character in it'
> find -type f
./file with EOL(?) character in it
> find -type f | wc -l
2

由于至少gnu wc似乎没有读取/计数空终止列表(从文件中删除)的选项,所以最简单的解决方案是不传递文件名,而是在每次找到文件时传递静态输出,例如在与上述相同的目录中

> find -type f -exec printf '\n' \; | wc -l
1

或者如果您find支持

> find -type f -printf '\n' | wc -l
1 

7

您可以使用命令ncdu。它将递归计算Linux目录包含多少个文件。这是输出示例:

在此处输入图片说明

它有一个进度条,如果您有许多文件,这将很方便:

在此处输入图片说明

要在Ubuntu上安装它:

sudo apt-get install -y ncdu

基准测试:我使用了https://archive.org/details/cv_corpus_v1.tar个文件,11 GB)作为必须计算文件数量的文件夹。

  • find . -type f | wc -l:大约1m20s完成
  • ncdu:大约1m20s完成

这主要是计算磁盘使用情况,而不是文件数量。可能不需要这种额外的开销。(除了需要安装其他软件包以使用标准POSIX实用程序完成的操作外)
hek2mgl

@ hek2mgl它确实计算文件数,如第一个屏幕截图中的红色所示。我花了几分钟处理了大约200万个文件,因此速度还不错。
Franck Dernoncourt,

2
@ hek2mgl我在答案中添加了可重现的基准,我运行了两次,但没有发现find . -type f | wc -l和之间的任何区别ncdu
Franck Dernoncourt,

2
是的,看起来像是在后台执行与后端find大致相同的系统调用。只是把他们拉了一下。duncdu
hek2mgl

1
@FranckDernoncourt喜欢它。我在文件夹中有大量文件,并且拥有进度条可以节省生命。感谢分享!
极客


4

要确定当前目录中有多少个文件,请输入ls -1 | wc -l。这用于wc(-l)的输出中的行数进行计数ls -1。它不计算点文件。请注意ls -l我在本HOWTO的早期版本中使用的(这是一个“ L”,而不是前面的示例中的“ 1”)实际上将使您的文件计数比实际计数大一。感谢Kam Nejad的观点。

如果您只想计算文件并且不包括符号链接(仅是您可以做的事情的一个例子),则可以使用ls -l | grep -v ^l | wc -l(这次是“ L”而不是“ 1”,我们希望在此处列出“ long”) 。grep检查以“ l”开头(指示链接)的任何行,并丢弃该行(-v)。

相对速度:在卸载的486SX25上,“ ls -1 / usr / bin / | wc -l”大约需要1.03秒(本机上的/ usr / bin /具有355个文件)。”ls -l /usr/bin/ | grep -v ^l | wc -l ”大约需要1.19秒。

资料来源:http : //www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x700.html


2
ls -l必须stat对每个文件进行系统调用以读取其大小,mtime和其他属性,这很慢。在大目录(超过100.000个文件)上,运行ls -l可能需要几分钟。因此,仅对文件计数,请始终使用ls -1 | wc -l
Marki555 2014年

A 486SX25,不错
cam8001 2015年

ls -1在大目录中仍然会很慢,因为它必须对文件进行排序。简单地printf '%s\n' *做同样的事情,并避免了外部ls调用(无论如何都是有问题的),但是最有效的解决方案是使用不执行任何排序的命令,例如find。(glob输出由shell排序。)
Tripleee

4

如果您需要递归计算特定文件类型 ,则可以执行以下操作:

find YOUR_PATH -name '*.html' -type f | wc -l 

-l 只是为了显示输出中的行数。


扩展名是文件名的一部分,可能不代表文件的类型
-Waxhead,

4

用bash:

使用()创建一个条目数组,并使用#获取计数。

FILES=(./*); echo ${#FILES[@]}

好的,这不会递归计数文件,但我想先显示简单的选项。常见的用例可能是创建文件的过渡备份。这将创建logfile.1,logfile.2,logfile.3等。

CNT=(./logfile*); mv logfile logfile.${#CNT[@]}

globstar启用bash 4+的递归计数(如@tripleee所述)

FILES=(**/*); echo ${#FILES[@]}

为了递归地获取文件数,我们仍然可以以相同的方式使用find。

FILES=(`find . -type f`); echo ${#FILES[@]}

现代shell支持**/*递归枚举。它仍然不如find大型目录有效,因为外壳程序必须对每个目录中的文件进行排序。
Tripleee

2

对于名称中带有空格的目录...(基于上述各种答案)-递归打印目录名称,其中包含以下文件数量:

find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done

示例(为便于阅读而格式化):

pwd
  /mnt/Vancouver/Programming/scripts/claws/corpus

ls -l
  total 8
  drwxr-xr-x 2 victoria victoria 4096 Mar 28 15:02 'Catabolism - Autophagy; Phagosomes; Mitophagy'
  drwxr-xr-x 3 victoria victoria 4096 Mar 29 16:04 'Catabolism - Lysosomes'

ls 'Catabolism - Autophagy; Phagosomes; Mitophagy'/ | wc -l
  138

## 2 dir (one with 28 files; other with 1 file):
ls 'Catabolism - Lysosomes'/ | wc -l
  29

使用tree以下命令可以更好地显示目录结构:

tree -L 3 -F .
  .
  ├── Catabolism - Autophagy; Phagosomes; Mitophagy/
  │   ├── 1
  │   ├── 10
  │   ├── [ ... SNIP! (138 files, total) ... ]
  │   ├── 98
  │   └── 99
  └── Catabolism - Lysosomes/
      ├── 1
      ├── 10
      ├── [ ... SNIP! (28 files, total) ... ]
      ├── 8
      ├── 9
      └── aaa/
          └── bbb

  3 directories, 167 files

man find | grep mindep
  -mindepth levels
    Do not apply any tests or actions at levels less than levels
    (a non-negative integer).  -mindepth 1 means process all files
    except the starting-points.

ls -p | grep -v /(以下使用)来自/unix/48492/list-only-regular-files-but-not-directories-in-current-directory中的答案2

find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done
./Catabolism - Autophagy; Phagosomes; Mitophagy: 138
./Catabolism - Lysosomes: 28
./Catabolism - Lysosomes/aaa: 1

应用: 我想在几百个目录(所有深度= 1)中找到最大文件数[以下输出再次格式化以提高可读性]:

date; pwd
    Fri Mar 29 20:08:08 PDT 2019
    /home/victoria/Mail/2_RESEARCH - NEWS

time find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done > ../../aaa
    0:00.03

[victoria@victoria 2_RESEARCH - NEWS]$ head -n5 ../../aaa
    ./RNA - Exosomes: 26
    ./Cellular Signaling - Receptors: 213
    ./Catabolism - Autophagy; Phagosomes; Mitophagy: 138
    ./Stress - Physiological, Cellular - General: 261
    ./Ancient DNA; Ancient Protein: 34

[victoria@victoria 2_RESEARCH - NEWS]$ sed -r 's/(^.*): ([0-9]{1,8}$)/\2: \1/g' ../../aaa | sort -V | (head; echo ''; tail)

    0: ./Genomics - Gene Drive
    1: ./Causality; Causal Relationships
    1: ./Cloning
    1: ./GenMAPP 2
    1: ./Pathway Interaction Database
    1: ./Wasps
    2: ./Cellular Signaling - Ras-MAPK Pathway
    2: ./Cell Death - Ferroptosis
    2: ./Diet - Apples
    2: ./Environment - Waste Management

    988: ./Genomics - PPM (Personalized & Precision Medicine)
    1113: ./Microbes - Pathogens, Parasites
    1418: ./Health - Female
    1420: ./Immunity, Inflammation - General
    1522: ./Science, Research - Miscellaneous
    1797: ./Genomics
    1910: ./Neuroscience, Neurobiology
    2740: ./Genomics - Functional
    3943: ./Cancer
    4375: ./Health - Disease 

sort -V是自然的一种。...因此,我在那些(Claws Mail)目录中的最大文件数是4375个文件。如果我左击(https://stackoverflow.com/a/55409116/1904943)这些文件名-它们都以数字命名,在每个目录中均以1开头-并填充到5位数字,我应该没问题。


附录

查找目录中文件,子目录的总数。

$ date; pwd
Tue 14 May 2019 04:08:31 PM PDT
/home/victoria/Mail/2_RESEARCH - NEWS

$ ls | head; echo; ls | tail
Acoustics
Ageing
Ageing - Calorie (Dietary) Restriction
Ageing - Senescence
Agriculture, Aquaculture, Fisheries
Ancient DNA; Ancient Protein
Anthropology, Archaeology
Ants
Archaeology
ARO-Relevant Literature, News

Transcriptome - CAGE
Transcriptome - FISSEQ
Transcriptome - RNA-seq
Translational Science, Medicine
Transposons
USACEHR-Relevant Literature
Vaccines
Vision, Eyes, Sight
Wasps
Women in Science, Medicine

$ find . -type f | wc -l
70214    ## files

$ find . -type d | wc -l
417      ## subdirectories

1

我写了ffcnt来在特定情况下加快递归文件计数:支持范围映射的旋转磁盘和文件系统。

它可能比基于lsfind基于YMMV的方法快一个数量级。


0

这里有许多正确答案。这是另一个!

find . -type f | sort | uniq -w 10 -c

.要查找的文件夹在哪里,是对目录10进行分组的字符数。


-1

查找类型f | wc -l

或(如果目录是当前目录)

找 。型f | wc -l


这将重复至少一个针对同一问题的答案。
库萨兰达

-1

这将完全正常。简单简短。如果要计算文件夹中存在的文件数。

ls | wc -l

3
首先,这不能回答问题。问题是关于递归计数目录中的文件,而您显示的命令不会这样做。此外,使用ls可以计算目录和文件。同样,如果您不打算添加任何新内容,甚至不正确地阅读问题,也没有理由回答旧问题。请不要这样做。
XFCC

-1

这种过滤格式的替代方法对所有可用的grub内核模块进行计数:

ls -l /boot/grub/*.mod | wc -l

-3
ls -l | grep -e -x -e -dr | wc -l 
  1. 长名单
  2. 过滤文件和目录
  3. 计算过滤的行数
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.