快速命令

时间:2008-09-02 18:19:29

标签: bash unix command ls

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

我假设服务器正在进行大量的inode排序。有没有办法加快ls命令以获取文件名的目录列表?我此时并不关心大小,日期,许可等。

19 个答案:

答案 0 :(得分:39)

ls -U

将执行ls而不进行排序。

答案 1 :(得分:11)

尝试使用:

find . -type f -maxdepth 1

这将仅列出目录中的文件,如果要列出文件和目录,则省略-type f参数。

答案 2 :(得分:8)

这个问题似乎很有趣,我正在浏览多个已发布的答案。为了理解发布的答案的效率,我已经在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 -f命令的运行速度比ls -U快一点。禁用颜色可能会导致这种改善。
  2. find命令运行第三,平均速度为2.738秒。
  3. 仅用ls跑了42.16秒。我的系统中lsls --color=auto
  4. 的别名
  5. 使用echo ./*的shell扩展功能运行了50.80秒。
  6. 基于tar的解决方案占用了大约37分钟。
  7. 当系统处于闲置状态时,所有测试都是单独进行的。

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

    为什么会发生这种情况?

答案 3 :(得分:6)

使用

ls -1 -f 

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

但在我的情况下,我需要检查某个特定目录是否包含超过10 000个文件。如果有超过10000个文件,我不再感兴趣的是有多少个文件。我只是退出程序,以便它运行得更快,并且不会尝试逐个阅读其余部分。如果少于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;

答案 4 :(得分:5)

我有一个目录,里面有400万个文件,唯一的方法就是我可以立即吐出文件而不需要大量的搅拌#

ls -1U

答案 5 :(得分:4)

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

ls > myls.txt &

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

不确定运行ls和获取更少数据的选项。您可以随时运行man ls进行检查。

答案 6 :(得分:4)

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

$ tar cvf /dev/null .

比我年长的人告诉我,“在当天”,单用户和恢复环境比现在更加有限。这就是这个技巧的来源。

答案 7 :(得分:4)

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

  • -1(无栏目)
  • -f(无排序)

答案 8 :(得分:2)

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

\ls

它会使通常的ls失效(ls --color = auto)。

答案 9 :(得分:2)

如果某个流程“没有回来”,我建议strace分析流程如何与操作系统进行交互。

如果是ls:

$strace ls

你会看到它在实际输出任何内容之前读取所有目录条目(getdents(2))。 (排序......就像这里已经提到的那样)

答案 10 :(得分:1)

要尝试的事情:

检查ls是否有别名?

alias ls

也许试试找?

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

希望这有帮助。

答案 11 :(得分:1)

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

在一个目录中拥有数百万个小文件,最好使用JFS或ReiserFS,它们对许多小尺寸文件具有更好的性能。

答案 12 :(得分:1)

find ./ -type f(将找到当前目录中的所有文件)怎么样?取消-type f找到所有内容。

答案 13 :(得分:1)

一些跟进: 你没有提到你正在运行的操作系统,这将有助于指出你正在使用的ls版本。这可能不是一个'bash'问题,就像问题一样。我的猜测是你正在使用GNU ls,它有一些在某些情况下很有用的功能,但在大目录上杀了你。

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

要“修复”此问题,您可以尝试:

ls -1#根本没有列

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

使用其他工具,例如find

答案 14 :(得分:1)

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

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

ls -U

或使用以下方法将文件列表发送到文件:

ls /Folder/path > ~/Desktop/List.txt

答案 15 :(得分:0)

我有一个目录,文件名中带有时间戳。我想查看最新文件的日期,发现<div class="headContainer headNavItems"> <div class="navItemsLeft"> <a id="hov" href="#">Test</a> <a id="hov" href="#">Test</a> <a id="hov" href="#">Test</a> <a id="hov" href="#">Test</a> </div> <div class="navItemsRight"> <a id="hov" href="#">Test</a> <a id="hov" href="#">Test</a> <a id="hov" href="#">Test</a> <a id="hov" href="#">Test</a> </div> </div> 的速度大约是find . -type f -maxdepth 1 | sort | tail -n 1的两倍。

答案 16 :(得分:0)

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

答案 17 :(得分:-1)

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

echo *

答案 18 :(得分:-2)

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

ls | xargs

如果这不起作用并且上面的 find 示例不起作用,请尝试将它们连接到 xargs ,因为它可以帮助可能导致您的内存使用问题。