哪个更有效:ls -l * ABC * vs ls -l | grep ABC

时间:2017-11-02 15:23:11

标签: linux bash unix

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

但哪一个效率更高?还有其他人,效率更高吗?

2 个答案:

答案 0 :(得分:4)

他们做了两件略有不同的事情。

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命令必须扫描当前目录,对其进行排序,获取所有内容的元数据,然后将其全部打印,以便(可能)大部分过滤掉单独的grep流程。

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

答案 1 :(得分:1)

Glob vs 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*

慢得多