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

Pra*_*kar 46 command-line ls

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

我收到以下命令:

ls -F |grep -v / | wc -l
Run Code Online (Sandbox Code Playgroud)

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

是否有任何 Ubuntu 命令?

l0b*_*0b0 46

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

find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c
Run Code Online (Sandbox Code Playgroud)

如果您不希望它是递归的,只需添加-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
Run Code Online (Sandbox Code Playgroud)

接受的答案进行比较:

$ ls -lR ./*.mp4 | wc -l
3
Run Code Online (Sandbox Code Playgroud)

或其他建议:

$ 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
Run Code Online (Sandbox Code Playgroud)

  • 虽然这个答案是正确且可靠的,但您可以使用 `-printf x` 代替 `-exec printf x \;`。即:`find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c` 不需要`-exec` 外部`printf` 命令,如果有很多文件会*非常慢*,因为`find` 必须[fork(2)](http://manpages .ubuntu.com/manpages/xenial/en/man2/fork.2.html) 关闭自身的副本,然后 [execve(2)](http://manpages.ubuntu.com/manpages/xenial/en/man2 /execve.2.html)`/usr/bin/printf`。使用`-exec printf x \;`,必须对*每个文件*执行一次。 (2认同)
  • 仅供参考,这在 macOS 上不起作用,“-printf:未知的主要或运算符” (2认同)

小智 29

在这里你可以这样做

ls -lR /path/to/dir/*.jpg | wc -l
Run Code Online (Sandbox Code Playgroud)

这给你数

  • 为什么是`-R`?当您只需要文件名时,为什么要执行完整的“stat”?为什么不是`ls -1 *.jpg| wc -l`?(好吧,如果您的文件名中包含换行符,则不起作用。在这种情况下,您应得的 ;-) ...) (6认同)
  • ...问题是“计算目录中的文件数”。此外,这将递归列出子目录的*所有内容* *名称以 .jpg 结尾*,而不是子目录中以 `.jpg` 结尾的文件。你有没有测试过? (2认同)
  • 如果目录中有太多文件(因为 `*.jpg` 由 shell 扩展,而不是由 `ls` 扩展)并且存在名称以连字符开头的文件,此操作也会失败。 (2认同)
  • @DavidRicherby 这会跳过以`.` 开头的名称。但它实际上适用于名称中的连字符,除非 `/path/to/dir` 是空字符串或以连字符开头的相对路径。但是**我之前错了**说`ls`用`?`替换了字符。当 stdout 是终端时会发生这种情况,但这里的输出是管道,因此 `ls` 将所有字符从文件名发送到 `wc`。**如果没有 `-q` 或 `-b` 标志来改变这种行为,那么这个答案是错误的**,因为文件名可以包含换行符。[l0b0 的回答](https://askubuntu.com/a/454568/22949) 没有这些问题。 (2认同)

小智 15

这个按扩展名按顺序查找、排序和列出所有文件:

find . -type f | sed 's/.*\.//' | sort | uniq -c
Run Code Online (Sandbox Code Playgroud)

  • 出色的!我只是添加一个`| 最后排序 -rn` ,如果只是当前目录,则可能是 `-mindepth 1` 。 (3认同)

xia*_*jie 9

我认为这很简单,如下命令。

$ find . -name "*.mp4" | wc -l
8
Run Code Online (Sandbox Code Playgroud)

或者

$ find . | grep -i ".mp4$" | wc -l
8
Run Code Online (Sandbox Code Playgroud)

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

所以我建议你使用-type f选项作为find参数如下。

$ find . -name "*.mp4" -type f | wc -l
8
Run Code Online (Sandbox Code Playgroud)

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