带有 ls -a 的 grep 命令无法正常工作?

Doe*_*ond 1 ls grep

我试图在我的主目录中列出一些隐藏文件,并且grep在与lscommand结合时遇到了一个非常奇怪的command行为。

  1. ls -a在我的主目录上执行并按预期获得了包括隐藏文件在内的所有文件。
  2. 我想列出所有以“xau”开头的隐藏文件,所以我执行了ls -a |grep -i .xau*它,它也按预期工作。
  3. 然后我ls -a |grep -i .x*在同一个目录中执行,但它根本没有列出任何内容
  4. 然后我错误地输入了ls -a |grep -i .*x (注意这次通配符 * 和字符 'x' 交换了位置),有趣的是它的行为与我在第 3 步中的意图相似。我试图用这个命令同样的事情ls -a .*x,并ls -a .*X但我得到没有这样的文件或目录错误。

在此处输入图片说明

在此处输入图片说明

在这里添加了实际的文本输出

你们中的一些人可能会问为什么不只是使用,ls -a .x*而是使用grep适当的颜色打印。所以有人可以向我解释一下吗?

Wil*_*ard 6

您正在遭受过早的全球扩张。

.xa*不会扩展,因为它与当前目录中的任何内容都不匹配。(Glob 区分大小写。)但是,.x* 确实匹配了一些文件,因此在grep看到它之前它会被 shell 扩展。

grep接收到多个参数时,它假定第一个是模式,其余的是用于搜索该模式的文件。

因此,在命令中ls -a | grep -i .x*, 的输出ls忽略,并在文件“.xsession-errors.old”中搜索模式“.xsession-errors”。不出所料,什么也没找到。

为了防止这种情况,请将您的特殊字符放在单引号或双引号内。例如:

ls -a | grep -i '.x*'
Run Code Online (Sandbox Code Playgroud)

您还患有正则表达式与全局混淆。

您似乎正在寻找以文字字符串“.x”开头并后跟任何内容的文件,但正则表达式的工作方式与文件 glob 不同。的* 在正则表达式的意思是“前面的字符0次或更多次”,而不是因为它在文件水珠“的任何字符的序列”。所以你可能想要的是:

ls -a | grep -i '^\.x'
Run Code Online (Sandbox Code Playgroud)

这将搜索名称以文字字符“.x”或“.X”开头的文件。实际上,由于您只指定了一个字母,因此您可以轻松地使用字符类而不是-i

ls -a | grep '^\.[xX]'
Run Code Online (Sandbox Code Playgroud)

关键是正则表达式与文件全局非常不同。

如果您只是ls -a | grep -i '.x*'按照建议的那样尝试,您会很惊讶地看到每个文件都将显示出来!(与ls -a直接输出相同,除了像在ls -a -1.

怎么来的?

好吧,在正则表达式中(但不是在 shell glob 中),句点 ( .) 表示“任何单个字符”。星号 ( *) 表示“零个或多个前面的字符”。所以正则表达式的.x*意思是“任何字符,后跟零个或多个字符‘x’的实例”。

当然,不允许有空文件名,因此每个文件名都包含“一个字符后跟至少零个‘x’”。:)


概括:

要得到你想要的结果,你需要明白两件事:

  1. 未加引号的特殊水珠字符(包括*?[]和其他一些人)将得到扩展的shell,再也不运行此命令之前看到他们,
  2. 正则表达式不同于(并且比文件 glob 更强大)。