至少有两种方法可以做同样的事情:) ls -l *ABC*和ls -l | grep ABC
但是哪一个更有效呢?还有没有其他更高效的?
发布于 2017-11-03 00:19:39
他们做了两件微妙的不同的事情。
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和语言环境设置,我不确定这两种排序是否会产生相同的顺序)。对于非常大的目录,排序可能是一个性能问题。(解决方案:避免创建非常大的目录。)除非当前目录中的所有内容都与*ABC*匹配,否则ls排序的条目将比shell少。
在ls -l | grep ABC中,ls命令必须扫描当前目录,对其进行排序,获取所有内容的元数据,然后将其全部打印出来,以便(可能)通过单独的grep进程过滤掉大部分内容。
我不知道哪个会更快。这可能取决于您当前目录的内容。但是,除非您正在处理大型目录或多次执行此操作,否则性能差异可能无关紧要。如果它确实很重要,请测量它;这是了解环境差异的唯一方法。
发布于 2017-11-02 23:29:57
Glob vs Grep。
ls -l *ABC*的工作方式是通配符与正则表达式匹配,并填充与该正则表达式匹配的文件名的数组。完成后,ls将简单地以长-l格式列出文件。
ls -l | grep ABC使用linux管道。管道的工作方式是将left命令的STD_OUT连接到right命令的STD_IN。因此,ls -l首先以长格式生成一个文件名的列表,然后管道将该列表传递给grep,grep根据匹配的正则表达式过滤出该列表。现在,假设这个列表有一百万个文件,当glob可以为你填充它时,没有必要传递整个列表。
因此,ls -l | grep ABC将比ls -l *ABC*慢得多
https://stackoverflow.com/questions/47078877
复制相似问题