Linux LS命令无法与*正则表达式量词

时间:2018-09-09 07:54:25

标签: linux ubuntu

如果我有目录结构

~/foo/foo1
~/foo/foo2
~/foo/foo3

如果我从〜/ foo中的终端发出以下命令,则输出以下命令:

  1. ls *foo1*返回总共0个目录
  2. ls *foo*返回3个目录foo1,foo2和foo3
  3. ls返回3个目录foo1,foo2和foo3
  4. ls -d *foo1*返回foo1
  5. ls | grep *foo1*返回foo1

为什么命令1。ls *Foo1*不返回Foo1?

enter image description here

2 个答案:

答案 0 :(得分:1)

这与shell文件glob(与正则表达式有所不同)无关,该文件工作正常(请参见echo *foo*echo *foo1*),并且与ls处理其参数的方式。

  1. ls *foo1*扩展为ls foo1。这确实列出了目录的内容,在您的情况下,该目录显然为空。

  2. ls -d *foo1*扩展为ls -d foo1。这会列出foo1目录本身而不是其内容。

  3. ls *foo*列出所有foo *目录的空内容。即使目录名称为空,这也会导致目录名称的输出。这些是ls仅在要列出多个目录时才创建的标头。

进一步阅读: http://tldp.org/LDP/abs/html/globbingref.html http://man7.org/linux/man-pages/man1/ls.1.html

答案 1 :(得分:0)

您真的很困惑,而且您对unix shell中的任何角色都不了解。

请仔细阅读globbing,尤其是glob(7)。它与正则表达式无关(在regex(7)中说明)。 *在外壳通配符模式和正则表达式中的作用和含义完全不同。 (因此,您在标题中提及“正则表达式”是错误的。)

在运行任何程序(甚至是任何内置命令,例如echo)之前,都会在外壳中发生。仔细阅读documentation of bash,其关于shell operation的部分以及有关shell expansions的章节。

ls(1)程序(即/bin/ls,因为/bin/在您的PATH variable中)永远不会在您的帐户中看到任何*或任何通配符文件模式情况。

因此,您正在输入ls *foo*。要了解会发生什么,请在前面键入echo,然后键入命令echo ls *foo*。您将通过Shell完成扩展。 /bin/ls程序正在得到扩展(execve(2)之后在fork(2)时在shell内完成)。

顺便说一句,由于其更好的zsh功能(我也可以尝试auto-completion),相对于bash,我更喜欢fish外壳而不是ls *foo*。我只需键入zsh,然后按 tab 键,然后我的*foo*交互式外壳程序立即展开zsh并编辑命令行。如果对此扩展感到满意,那么只需按 return 键,命令行就会由我的zsh shell解析并执行。如果该扩展不是我想要的,ls允许我编辑命令行。

此命令扩展并非特定于ls。由Shell启动的任何程序的参数列表都是通过Shell扩展获得的。在某些情况下,您可能使用stat(1)而不是ls(1)(并且您的外壳可能已经定义了aliases,所以您的*可能是别名其他)。

由于外壳扩展的工作方式,我建议文件名中不要包含空格或特殊字符(例如控制字符和换行符,甚至是?minSdkVersion)。但是,如果要处理名称奇怪的文件路径,可以使用quoting技术。

另请参阅Parsing Posix [S]hell上的Yann Regis-Gianas出色的FOSDEM2018演讲

PS。其他操作系统的工作方式有所不同。对于Windows(我不知道并且从没使用过),有传言说命令扩展发生在程序内部(emem)(在某些crt0中是等效的)。