计算具有特定扩展名的特定目录中的文件总数


32

我要计算以“ .mp4”扩展名结尾的特定目录中的文件总数。

我得到以下命令:

ls -F |grep -v / | wc -l

它计算特定目录中的所有文件,但我希望以.mp4扩展名结尾的文件计数。

是否有任何Ubuntu命令?


2
一个简单,正确,直接的答案是@ louis-matthijssen。ls -1在这种情况下,对换行符的处理使解析ls输出变得明智。标记为-R的标志是错误的。
Rmano 2014年

Answers:


19

在这里你可以这样

ls -lR /path/to/dir/*.jpg | wc -l

这给你数


5
为什么-R呢?stat只需要文件名时为什么要进行完整备份?为什么不ls -1 *.jpg| wc -l呢?(好的,如果您的文件名中包含换行符,则不起作用。在这种情况下,您应得到它;-) ...)
Rmano

2
...问题是“计算目录中的文件数”。此外,这将递归列出名称以.jpg结尾的子目录的所有内容,而不是以结尾的子目录中的文件。你有没有测试过?.jpg
Rmano 2014年

1
这个问题说“特定目录中的文件”,这意味着不需要子目录递归。
David Richerby 2014年

1
如果目录中的文件太多(因为*.jpg被shell扩展,而不是被扩展ls),并且文件名中以连字符开头,则失败。
David Richerby 2014年

2
@DavidRicherby这会跳过以开头的名称.。但是它实际上可以与名称中的连字符一起使用,除非/path/to/dir是空字符串或以连字符开头的相对路径。但是我之前说过ls用替换字符是错误的?。当stdout是终端时会发生这种情况,但是这里的输出是管道,因此ls将文件名中的所有字符发送到wc如果没有使用-q-b标志来更改该行为,则会使此答案错误,因为文件名可以包含换行符。l0b0的答案没有这些问题。
伊莱亚·卡根

42

不幸的是,这种良性问题很难以支持所有文件名并且可移植的方式解决。是安全的(它处理隐藏文件,包含空格,破折号甚至换行符的路径)并且与POSIX兼容

find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c

如果您不希望它是递归的,只需添加-maxdepth 1

您不应该解析ls输出。

测试:

$ cd -- "$(mktemp -d)"
$ touch -- -foo.mp4 .bar.mp4 .bat.mp4 'baz.mp4
> ban.mp4'
$ find . -mindepth 1 -type f -name "*.mp4" -exec printf x \; | wc -c
4

接受的答案进行比较:

$ ls -lR ./*.mp4 | wc -l
3

或其他建议:

$ find . -name "*.mp4" | wc -l
5
$ ls -1 *.mp4 | wc -l
ls: invalid option -- '.'
Try 'ls --help' for more information.
0
$ find . -name "*.mp4" | wc -c # Answer fixed at a later time
51
$ find . -name "*.mp4" | wc -l
5
$ find . | grep -i ".mp4$" | wc -l
5
$ ls . | grep ".mp4$" | wc -l
3

2
尽管此答案是正确且可靠的,但您可以使用-printf x代替-exec printf x \;。那就是:find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c 不需要-exec外部printf命令,如果有许多文件,它将非常慢,因为find必须先将自身的副本派生(2),然后再执行(2)execve /usr/bin/printf。使用-exec printf x \;,必须对每个文件执行一次。
伊莱亚·卡根

-printf不支持POSIXfind,这就是为什么我不使用它。
l0b0

1
都不是-mindepth-maxdepth您使用的。
伊利亚·卡根

好点,我还没有意识到!
l0b0

BSD find包含-mindepth-maxdepth,但不包含-printf,所以我很欣赏双方的包容性。
约瑟夫

11

该文件按扩展名依次查找,排序和列出所有文件:

find . -type f | sed 's/.*\.//' | sort | uniq -c

优秀!我只想| sort -rn在末尾添加一个,-mindepth 1如果只是当前目录,也可以添加一个。
巴勃罗A

也许可以通过管道head -n获得前n个。
拉曼

非常好的答案,非常感谢
Dennis Golomazov

5

我认为这很简单,只需执行以下命令即可。

$ find . -name "*.mp4" | wc -l
8

要么

$ find . | grep -i ".mp4$" | wc -l
8

我认为上述命令计算文件和目录名称的数量 *.mp4

因此,我建议您使用-type foption作为find参数,如下所示。

$ find . -name "*.mp4" -type f | wc -l
8

另外,ls -lR可以用作find .


2

您可以使用ls -1 *.mp4 | wc -l

这将列出所有以结尾的.mp4文件,将每个文件打印在新行(ls -1 *.mp4)上,并将输出通过管道传输到wc该行,该输出将使用该-l标志计算新行数。


不知道为什么要拒​​绝投票,它能起作用
Panther

由于*.mp4不是由Shell扩展ls,因此如果.mp4目录中的文件太多而无法将其列表ls作为参数传递,则失败。
David Richerby 2014年

@Rmana在包含名为--.mp4
David Richerby

@DavidRicherby是的,您是对的。--将解决第二种情况;前者会出现错误消息(您需要很多文件!),而这里还有另一个不错的问题。极端情况,但值得注意的是。
Rmano 2014年

1
@Rmano如果不添加-q-b,则不会容忍文件名中的换行符。如果ls -1 *.mp4从没有管道的终端运行,则ls看到其stdout是终端,并-q隐含地显示?s。但是,当通过管道传输输出时,该行为消失了。ls -1 *.mp4 | wc -l如果有换行符,请多算。ls -1 *.mp4 | cat显示wc“看到”的内容。(类似地,-1当stdout 不是终端时,它是隐含的,因此它是可选的。)ls -1q -- *.mp4 | wc -l几乎可以工作,但不适用于零.mp4文件。
伊莱亚·卡根

0

这应该给你带.mp4的文件列表

ls /path/to/directory | grep ".mp4$"

当与结合wc -l时会给你计数

ls /path/to/directory | grep ".mp4$" | wc -l

如果要搜索以包含子目录

ls -lR /path/to/directory | grep ".mp4$" | wc -l

没有计数
-Panther

wc -l
Back.Slash

使用不带管道的ls来grep并缩短答案。现在至少已发布两次。
Panther

@ bodhi.zazen ls /directory/*.mp4会导致Shell扩展glob并执行类似的操作,ls /directory/file1.mp4 /directory/file2.mp4 ...如果该目录包含的mp4文件超出了作为参数传递给的mp4文件,则此操作将失败ls
David Richerby 2014年

@DavidRicherby-这不是我的ls命令,我使用find;)
Panther


0
ls | grep --count \.csv$

替换(.csv为所需的扩展名)

说明:我认为一个简单的方案是获取文件列表,并使用grep计算扩展名。\.匹配.$匹配行尾的扩展名。之所以起作用,是因为通过管道输出ls的输出时,每行发送一个文件名,您可以通过运行以下命令进行验证:

ls | cat

1
请注意grep --count,您也可以使用代替grep -c
Mohsin Raza

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.