【问题标题】:Linux LS command does not work correctly with * regular expression quantifier [closed]Linux LS 命令不能与 * 正则表达式量词一起正常工作 [关闭]
【发布时间】:2018-09-09 07:54:25
【问题描述】:

如果我有目录结构

~/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?

【问题讨论】:

  • 我不知道你为什么要在你所有的名字周围加上*。使用ls -l foo2ls -d foo1ls | grep foo1 等,您会得到相同的结果。
  • 我的问题是正则表达式应该可以工作。正确的?我知道替代方案。
  • 您的所有命令都不使用正则表达式。你所有的命令“工作”;你没有解释你认为你看到的输出有什么问题。
  • 仔细阅读glob(7)。 Shell 通配符模式与regex(7)s 完全无关,并且具有不同的语法。所以ls 从来都不是用来处理正则表达式的。请注意,通配符扩展发生在 shell 中,ls 之类的程序不会这样做。

标签: linux ubuntu


【解决方案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

【讨论】:

  • 我很确定ls -d 没有列出目录的内容。
  • 对,抱歉,打错字了。
【解决方案2】:

你真的很迷茫,你对任何unix shell的作用都不太了解。

仔细阅读globbing,尤其是glob(7)。它与正则表达式无关(在regex(7) 中解释)。 * 在 shell 通配符模式和正则表达式中具有非常不同的作用和含义。 (所以你在标题中提到“正则表达式”是错误的)。

通配发生在 shell 中,运行任何程序(甚至任何内置命令,如 echo)之前。仔细阅读documentation of bashshell 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 外壳而不是bash,因为它具有更好的auto-completion 功能(您也可以尝试fish)。我只需键入ls *foo*,然后按tab 键,我的zsh 交互式shell 会立即展开*foo* 并编辑命令行。如果我对扩展感到满意,我只需按下 return 键,命令行就会被我的zsh shell 解析和执行。如果该扩展不是我想要的,zsh 允许我编辑命令行。

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

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

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

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

【讨论】:

  • 也许还指向mywiki.wooledge.org/ParsingLs,它更详细地解释了一些极端情况。
  • @tripleee:那个页面很有趣,但我觉得这不是 OP 所要求的。解析ls输出与管道命令相关,OP的问题没有提到它们。
  • 绝对的;但它也解释了例如ls 在各种情况下的行为方式有何不同,例如当它接收到目录参数时(没有-d)。
  • 要了解像ls 这样的命令,我强烈建议您先阅读该命令的文档,即ls(1) 手册页。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-29
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 2012-06-21
相关资源
最近更新 更多