为什么`ls -l`比我算的文件多?

显然我无法计算。 我认为/media有三个文件

 $ tree /media /media ├── foo ├── onex └── zanna 3 directories, 0 files 

但是, ls -l找到12。

 $ ls -l /media total 12 drwxr-xr-x 2 root root 4096 Jul 31 20:57 foo drwxrwxr-x 2 root root 4096 Jun 26 06:36 onex drwxr-x---+ 2 root root 4096 Aug 7 21:17 zanna 

并且,如果我做ls -la我只得到...除了以上,但计数total 20

解释是什么?

您看到的12不是文件数,而是消耗的磁盘块数。

来自info coreutils 'ls invocation'

  For each directory that is listed, preface the files with a line `total BLOCKS', where BLOCKS is the total disk allocation for all files in that directory. The block size currently defaults to 1024 bytes, but this can be overridden (*note Block size::). The BLOCKS computed counts each hard link separately; this is arguably a deficiency. 

当你使用ls -la而不是ls -l时,总数从12变为20 ,因为你计算了另外两个目录: ... 您为每个(空)目录使用了四个磁盘块,因此总数从3×4变为5×4。(很可能,每个目录使用一个 4096字节的磁盘块;如info页面所示,该实用程序不检查磁盘格式,但假定块大小为1024除非另有说明。)

如果你想简单地获取文件数量,你可能会尝试类似的东西

 ls | wc -l 

user4556274已经回答了原因 。 我的回答仅用于提供有关如何正确计算文件的其他信息。

在Unix社区中,普遍的共识是解析ls的输出是一个非常糟糕的主意,因为文件名可以包含控制字符或隐藏字符。 例如,由于文件名中有换行符,我们有ls | wc -l ls | wc -l告诉我们ls的输出中有5行(它确实有),但实际上目录中只有4个文件。

 $> touch FILE$'\n'NAME $> ls file1.txt file2.txt file3.txt FILE?NAME $> ls | wc -l 5 

find命令通常用于解析文件名,可以通过打印inode编号来帮助我们。 无论是目录还是文件,它只有一个唯一的inode编号。 因此,使用-printf "%i\n"并排除. via -not -name "." 我们可以准确计算文件数量。 (注意使用-maxdepth 1来防止递归下降到子目录中)

 $> find -maxdepth 1 -not -name "." -print ./file2.txt ./file1.txt ./FILE?NAME ./file3.txt $> find -maxdepth 1 -not -name "." -printf "%i\n" | wc -l 4 

stat可以使用相同的技巧来计算每行的inode数量:

 $> LC_ALL=C stat ./* --printf "%i\n" | wc -l 4 

另一种方法是使用通配符。 (注意,这个测试使用一个不同的目录来测试这种方法是否下降到子目录中,它不会–16是我~/bin已validation的项目数)

 $> count=0; for item in ~/bin/* ; do count=$(($count+1)) ; echo $count ; done | tail -n 1 16 

Python还可以通过打印给定我的os.listdir()函数的列表长度来处理有问题的文件名(这是非递归的,并且只列出作为参数给出的目录中的项目)。

 $> python -c "import os ; print os.listdir('.')" ['file2.txt', 'file1.txt', 'FILE\nNAME', 'file3.txt'] $> python -c "import os ; print(len(os.listdir('.')))" 4