递归计算Linux目录中的文件

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

我找到了这个:

find DIR_NAME -type f ¦ wc -l

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

查找:路径必须在表达式之前:

843256 次浏览

这应该工作:

find DIR_NAME -type f | wc -l

说明:

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

备注:

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

解释为什么你的例子不起作用:

在您展示的命令中,您不使用“管道”(|)来连接两个命令,而是使用断开的栏(¦),shell无法将其识别为命令或类似的东西。这就是为什么您会收到错误消息。

对于当前目录:

find -type f | wc -l

要确定当前目录中有多少文件,请输入ls -1 | wc -l。这使用wc来计算ls -1输出中(-l)的行数。它不包括点文件。请注意,我在以前版本的HOWTO中使用的ls -l(这是一个“L”而不是“1”)实际上会给您一个比实际计数大1的文件计数。感谢Kam Nejad提出这一点。

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

相对速度:“ls-1 /usr/bin/|wc-l”在卸载的486SX25上大约需要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

如果您想要细分当前目录下每个目录中的文件数:

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

当然,这可以在一行上进行。括号澄清了应该观察谁的输出wc -l(在本例中为find $i -type f)。

您可以使用

$ tree

安装软件包后

$ sudo apt-get install tree

(在Debian/Mint/UbuntuLinux机器上)。

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

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

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

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

这将在GNU风格中工作,只需省略BSD linux(例如OSX)回显命令中的-e。

如果您想避免错误情况,请不要让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 -l2

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

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

如果你的find支持它

> find -type f -printf '\n' | wc -l1

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

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

它可以处理奇怪的东西,例如包含空格括号甚至新行的文件名。它还按文件数量对输出进行排序。

您可以增加-maxdepth之后的数字以计算子目录。请记住,这可能需要很长时间,特别是如果您有一个高度嵌套的目录结构和一个高-maxdepth数字。

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

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

在我的电脑上,在接受的答案中,rsyncfind | wc -l快一点:

$ rsync --stats --dry-run -ax /path/to/dir /tmp
Number of files: 173076Number of files transferred: 150481Total file size: 8414946241 bytesTotal transferred file size: 8414932602 bytes

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

备注:

  • 第一行是文件、目录、符号链接等的计数,这就是为什么它比第二行大。
  • --dry-run(或简称-n)选项对于不实际传输文件很重要!
  • 我使用-x选项“不要跨越文件系统边界”,这意味着如果您为/执行它并且附加了外部硬盘,它将仅计算根分区上的文件。
ls -l | grep -e -x -e -dr | wc -l
  1. 长名单
  2. 过滤文件和目录
  3. 计算过滤线否

这里有很多正确答案。这里还有一个!

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

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

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

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

使用bash:

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

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

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

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

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

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

要以递归方式获取文件计数,我们仍然可以以相同的方式使用查找。

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

查找-type f|wc-l

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

查找。-type f|wc-l

这将完全正常工作。简单简短。如果您想计算文件夹中存在的文件数量。

ls | wc -l

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

在此处输入图片描述

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

在此处输入图片描述

在Ubuntu上安装它:

sudo apt-get install -y ncdu

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

  • find . -type f | wc -l:1m20s左右完成
  • ncdu:1m20s左右完成

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

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

注意:-printf选项仅适用于从GNU findutils查找。您可能需要安装它,例如在Mac上。

tree $DIR_PATH | tail -1

样品输出:

5309个目录,2122个文件

如果你需要的是计数特定文件类型递归,你可以这样做:

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

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

如果您需要排除某些文件夹,请使用-not -path

find . -not -path './node_modules/*' -name '*.js' -type f | wc -l

对于名称中带有空格的目录…(基于上面的各种答案)-递归打印目录名称及其中的文件数:

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 -ltotal 8drwxr-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 -l138
## 2 dir (one with 28 files; other with 1 file):ls 'Catabolism - Lysosomes'/ | wc -l29

使用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 levelsDo not apply any tests or actions at levels less than levels(a non-negative integer).  -mindepth 1 means process all filesexcept the starting-points.

ls -p | grep -v /(下面使用)来自https://unix.stackexchange.com/questions/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; pwdFri 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 > ../../aaa0: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 Drive1: ./Causality; Causal Relationships1: ./Cloning1: ./GenMAPP 21: ./Pathway Interaction Database1: ./Wasps2: ./Cellular Signaling - Ras-MAPK Pathway2: ./Cell Death - Ferroptosis2: ./Diet - Apples2: ./Environment - Waste Management
988: ./Genomics - PPM (Personalized & Precision Medicine)1113: ./Microbes - Pathogens, Parasites1418: ./Health - Female1420: ./Immunity, Inflammation - General1522: ./Science, Research - Miscellaneous1797: ./Genomics1910: ./Neuroscience, Neurobiology2740: ./Genomics - Functional3943: ./Cancer4375: ./Health - Disease

sort -V是一个自然的排序……所以,我在任何这些(爪邮件)目录中的最大文件数是4375个文件。如果我左垫(https://stackoverflow.com/a/55409116/1904943)这些文件名-它们都是以数字命名的,从1开始,在每个目录中-并垫到5位总数字,我应该没问题。


增编

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

$ date; pwdTue 14 May 2019 04:08:31 PM PDT/home/victoria/Mail/2_RESEARCH - NEWS
$ ls | head; echo; ls | tailAcousticsAgeingAgeing - Calorie (Dietary) RestrictionAgeing - SenescenceAgriculture, Aquaculture, FisheriesAncient DNA; Ancient ProteinAnthropology, ArchaeologyAntsArchaeologyARO-Relevant Literature, News
Transcriptome - CAGETranscriptome - FISSEQTranscriptome - RNA-seqTranslational Science, MedicineTransposonsUSACEHR-Relevant LiteratureVaccinesVision, Eyes, SightWaspsWomen in Science, Medicine
$ find . -type f | wc -l70214    ## files
$ find . -type d | wc -l417      ## subdirectories

假设您想要每个目录的总文件,请尝试:

for d in `find YOUR_SUBDIR_HERE -type d`; doprintf "$d - files > "find $d -type f | wc -ldone

对于当前dir,请尝试以下操作:

for d in `find . -type d`; do printf "$d - files > "; find $d -type f | wc -l; done;

如果你有很长的空格名称,你需要更改IFS,如下所示:

OIFS=$IFS; IFS=$'\n'for d in `find . -type d`; do printf "$d - files > "; find $d -type f | wc -l; doneIFS=$OIFS

根据上面给出的回复和评论,我想出了以下文件计数列表。特别是它是@Greg Bell提供的的解决方案的组合,以及@Arch Stanton的评论&@Schneems

计算当前目录和子目录中的所有文件

function countit { find . -maxdepth 1000000 -type d -print0 | while IFS= read -r -d '' i ; do file_count=$(find "$i" -type f | wc -l) ; echo "$file_count: $i" ; done }; countit | sort -n -r >file-count.txt

计算当前目录和子目录中所有给定名称的文件

function countit { find . -maxdepth 1000000 -type d -print0 | while IFS= read -r -d '' i ; do file_count=$(find "$i" -type f | grep <enter_filename_here> | wc -l) ; echo "$file_count: $i" ; done }; countit | sort -n -r >file-with-name-count.txt

我们可以使用命令递归显示所有文件和文件夹。以及它在输出的最后一行显示文件夹和文件的计数。

$ tree path/to/folder/path/to/folder/├── a-first.html├── b-second.html├── subfolder│   ├── readme.html│   ├── code.cpp│   └── code.h└── z-last-file.html
1 directories, 6 files

对于树命令中的最后一行输出,我们可以在它的输出上使用尾巴命令

$ tree path/to/folder/ | tail -11 directories, 6 files

为了安装树,我们可以使用下面的命令

$ sudo apt-get install tree