至少有两种方法可以做同样的事情:)
ls -l *ABC*
和ls -l | grep ABC
但哪一个效率更高?还有其他人,效率更高吗?
答案 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*