49

我必须得到一个包含大约 200 万个文件的目录列表,但是当我对它执行ls命令时,什么都没有返回。我等了3个小时。我试过ls | tee directory.txt了,但这似乎永远挂起。

我假设服务器正在进行大量的 inode 排序。有什么方法可以加快ls命令以获取文件名的目录列表?我现在不在乎大小、日期、许可等。

4

19 回答 19

44
ls -U

将执行 ls 而不进行排序。

另一个缓慢的来源是--color. 在一些 linux 机器上,有一个方便的别名添加--color=auto'到 ls 调用中,使其查找找到的每个文件的文件属性(慢),以着色显示。这可以通过ls -U --color=never或避免\ls -U

于 2008-09-02T18:25:34.273 回答
17

我有一个目录,里面有 400 万个文件,我让 ls 立即吐出文件而无需先进行大量搅动的唯一方法是

ls -1U
于 2015-11-18T16:37:54.753 回答
14

尝试使用:

find . -type f -maxdepth 1

这只会列出目录中的文件,-type f如果要列出文件和目录,请省略参数。

于 2008-09-02T18:23:11.160 回答
9

这个问题似乎很有趣,我正在查看已发布的多个答案。为了了解发布的答案的效率,我在 200 万个文件上执行了它们,发现结果如下。

$ time tar cvf /dev/null . &> /tmp/file-count

real    37m16.553s
user    0m11.525s
sys     0m41.291s

------------------------------------------------------

$ time echo ./* &> /tmp/file-count

real    0m50.808s
user    0m49.291s
sys     0m1.404s

------------------------------------------------------

$ time ls &> /tmp/file-count

real    0m42.167s
user    0m40.323s
sys     0m1.648s

------------------------------------------------------

$ time find . &> /tmp/file-count

real    0m2.738s
user    0m1.044s
sys     0m1.684s

------------------------------------------------------

$ time ls -U &> /tmp/file-count

real    0m2.494s
user    0m0.848s
sys     0m1.452s


------------------------------------------------------

$ time ls -f &> /tmp/file-count

real    0m2.313s
user    0m0.856s
sys     0m1.448s

------------------------------------------------------

总结结果

  1. ls -fcommand 的运行速度比ls -U. 禁用颜色可能会导致这种改进。
  2. find命令以 2.738 秒的平均速度运行第三。
  3. 跑步只用ls了 42.16 秒。在我的系统中,这ls是一个别名ls --color=auto
  4. 使用 shell 扩展功能并echo ./*运行了 50.80 秒。
  5. 并且tar基于解决方案花费了大约 37 分钟。

当系统处于空闲状态时,所有测试都是单独进行的。

这里要注意的一件重要事情是,文件列表不会在终端中打印,而是被重定向到文件,并且稍后使用wc命令计算文件计数。如果输出打印在屏幕上,则命令运行速度太慢。

任何想法为什么会发生这种情况?

于 2014-11-02T13:38:50.443 回答
6

使用

ls -1 -f 

大约快 10 倍,而且很容易做到(我测试了 100 万个文件,但我原来的问题有 6 800 000 000 个文件)

但就我而言,我需要检查某个特定目录是否包含超过 10 000 个文件。如果有超过 10 000 个文件,我不再对有多少文件感兴趣。我只是退出了该程序,以便它运行得更快,并且不会尝试一一阅读其余内容。如果少于 10 000,我将打印确切的数量。如果您为参数指定的值大于文件数量,我的程序的速度与 ls -1 -f 非常相似。

您可以通过键入以下内容在当前目录中使用我的程序 find_if_more.pl:

find_if_more.pl 999999999

如果您只是对有超过 n 个文件感兴趣,那么脚本将比 ls -1 -f 更快地完成大量文件。

#!/usr/bin/perl
    use warnings;
    my ($maxcount) = @ARGV;
    my $dir = '.';
    $filecount = 0;
    if (not defined $maxcount) {
      die "Need maxcount\n";
    }
    opendir(DIR, $dir) or die $!;
    while (my $file = readdir(DIR)) {
        $filecount = $filecount + 1;
        last if $filecount> $maxcount
    }
    print $filecount;
    closedir(DIR);
    exit 0;
于 2014-11-01T16:09:05.407 回答
6

这将是最快的选项 AFAIK: ls -1 -f

  • -1(无列)
  • -f(没有排序)
于 2013-08-27T11:31:35.373 回答
5

您可以重定向输出并在后台运行 ls 进程。

ls > myls.txt &

这将允许您在运行时继续您的业务。它不会锁定你的外壳。

不确定运行 ls 和获取更少数据的选项有哪些。你可以随时跑过去man ls检查。

于 2008-09-02T18:23:21.020 回答
4

这可能不是一个有用的答案,但如果你没有,find你可以凑合tar

$ tar cvf /dev/null .

比我年长的人告诉我,“回到过去”,单用户和恢复环境比现在更受限制。这就是这个技巧的来源。

于 2010-09-01T16:03:18.110 回答
3

我假设您使用的是 GNU ls?尝试

\ls

它将取消通常的 ls (ls --color=auto) 的别名。

于 2008-09-02T18:24:46.413 回答
2

如果一个进程“没有回来”,我建议使用strace来分析一个进程是如何与操作系统交互的。

如果是 ls:

$strace ls

您会看到它在实际输出任何内容之前读取了所有目录条目( getdents(2) )。(排序……正如这里已经提到的)

于 2008-09-02T20:17:46.500 回答
1

怎么样find ./ -type f(它将找到当前目录中的所有文件)?取下来-type f找到一切。

于 2008-09-02T18:20:23.163 回答
1

要尝试的事情:

检查 ls 没有别名?

alias ls

也许尝试 find ?

find . \( -type d -name . -prune \) -o \( -type f -print \)

希望这可以帮助。

于 2008-09-02T18:23:16.103 回答
1

您使用的是什么分区类型?

在一个目录中有数百万个小文件,使用 JFS 或 ReiserFS 可能是一个好主意,它们对许多小文件有更好的性能。

于 2008-09-02T18:56:24.870 回答
1

一些后续行动:您没有提及您正在运行的操作系统,这将有助于指示您正在使用的 ls 版本。这可能不像 ls 问题那样是“bash”问题。我的猜测是您使用的是 GNU ls,它具有一些在某些情况下有用的功能,但在大目录中会杀死您。

GNU ls 试图对列进行更漂亮的排列。GNU ls 尝试对所有文件名进行智能排列。在一个巨大的目录中,这将需要一些时间和内存。

要“解决”这个问题,您可以尝试:

ls -1# 根本没有列

在某个地方找到 BSD ls,http: //www.freebsd.org/cgi/cvsweb.cgi/src/bin/ls/并在您的大目录中使用它。

使用其他工具,例如 find

于 2009-10-30T16:01:00.403 回答
1

有几种方法可以获取文件列表:

使用此命令获取不排序的列表:

ls -U

或使用以下命令将文件列表发送到文件:

ls /Folder/path > ~/Desktop/List.txt
于 2014-10-10T08:50:39.740 回答
0

您应该提供有关您正在使用的操作系统和文件系统类型的信息。在某些风格的 UNIX 和某些文件系统上,您可能能够使用这些命令ffncheck作为替代方案。

于 2008-09-02T19:55:17.443 回答
0

我有一个文件名中带有时间戳的目录。我想检查最新文件的日期,发现find . -type f -maxdepth 1 | sort | tail -n 1它的速度大约是ls -alh.

于 2020-04-27T22:51:09.780 回答
-1

这里有很多其他好的解决方案,但为了完整性:

echo *
于 2008-09-03T02:38:57.160 回答
-2

您还可以使用xargs。只需通过xargs管道输出ls的输出。

ls | xargs

如果这不起作用并且上面的查找示例不起作用,请尝试将它们通过管道传输到xargs,因为它可以帮助内存使用可能导致您的问题。

于 2008-09-16T19:00:17.237 回答