【问题标题】:Which is more efficient : ls -l *ABC* vs ls -l | grep ABC哪个更有效: ls -l *ABC* vs ls -l | grep ABC
【发布时间】:2017-11-02 15:23:11
【问题描述】:

至少有两种方法可以做同样的事情:) ls -l *ABC*ls -l | grep ABC

但是哪一个更有效呢?还有其他更高效的吗?

【问题讨论】:

  • 当然ls -l *ABC*
  • 在几乎所有情况下,单个过程都比管道更有效。
  • 用例是什么?如果你想将文件列表传递给不同的程序,或者在你的 shell 脚本中迭代它们,你根本不应该使用ls——不仅仅是出于性能原因,而是出于正确性 原因也是如此。见Why you shouldn't parse the output of ls
  • @CharlesDuffy 有时人们只想列出文件...
  • @123,当然,但区分这里是否是这种情况很有用。坦率地说,如果有人“只想[s]列出文件”,那么性能很重要(除非它是一个非常大的目录,在这种情况下,最大的收益来自告诉ls不要排序)。

标签: linux bash unix


【解决方案1】:

他们做了两件微妙不同的事情。

ls -l *ABC* 列出当前目录中名称包含ABC(且不以. 开头)的所有条目。

ls -l | grep ABC 列出当前目录中名称不以. 开头的所有条目,然后过滤掉所有不包含ABC 的行。

ls -l 列出用户名和组名以及文件名,因此如果碰巧有名称包含ABC 的用户或组拥有的文件,无论其名称如何,它们都会被列出。大多数组名和用户名不包含大写字母,但这不是硬性要求,您可能希望对其他模式(如abc)执行相同的操作。如果该模式恰好包含在单词total 中,您将匹配ls -l 输出的第一行。

更模糊地说,文件名可以合法地包含除/ 和空字符之外的任何字符——包括换行符。使用这样的名称是一个非常糟糕的主意,但是这样的文件名将列在两行或多行中,而grep 会在行上运行。

ls -l 的输出旨在供人类阅读。它并不是真的打算自动处理。

ls -l *ABC* 更清楚、更直接地表达了你的意思。在考虑性能之前考虑一下。除非您的当前目录非常庞大,否则任何性能差异都可能被打印输出所花费的时间所淹没。

说了这么多,让我们看看可能的性能问题。

ls -l *ABC* 中,*ABC* 通配符由 shell 处理; ls 只看到一个参数列表。它需要 shell 扫描当前目录并构建一个匹配模式的文件名排序列表。然后ls 命令将再次对其进行排序(根据您的shell 和语言环境设置,我不确定这两种排序是否会产生相同的顺序)。对于非常大的目录,排序可能是一个性能问题。 (解决方案:避免创建非常大的目录。)ls 将比 shell 排序更少的项目——除非当前目录中的所有内容都与 *ABC* 匹配。

ls -l | grep ABC 中,ls 命令必须扫描当前目录,将其全部排序,获取所有内容的元数据,然后将其全部打印出来,以便(可能)大部分内容被单独的 @987654344 过滤掉@进程。

我不知道哪个会更快。这可能取决于您当前目录的内容。但除非您正在处理巨大的目录或多次执行此操作,否则性能差异可能并不重要。如果它确实重要,请测量它;这是了解您的环境中的差异的唯一方法。

【讨论】:

    【解决方案2】:

    Glob 与 Grep。

    ls -l *ABC* 的工作方式是通配符匹配正则表达式并填充与该正则表达式匹配的文件名数组。完成后, ls 会简单地列出长 -l 格式的文件。

    ls -l | grep ABC 使用 linux 管道。管道的工作方式是将左侧命令的 STD_OUT 连接到右侧命令的 STD_IN。因此 ls -l 首先生成一个所有长格式文件名的列表,然后通过管道将此列表传递给 grep,grep 根据匹配的正则表达式过滤掉该列表。 现在,假设这个列表包含一百万个文件,当 glob 可以为您填充它时,没有必要传递整个列表。

    因此ls -l | grep ABC 会比ls -l *ABC* 慢很多

    【讨论】:

    • 重要的是要区分在*ABC* 的情况下,文件名列表是由shellls 甚至启动之前生成的。这意味着ls | grep 情况下不存在一些限制——本地平台的最大命令行长度是相关的。
    • (与 printf '%s\0' *ABC* | xargs -0 ls -l 对比,如果名称多于一个可以处理的名称,则通过拆分为多个 ls 调用来避免该限制)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 2012-11-10
    相关资源
    最近更新 更多