鱼壳中的全局匹配(通配符)与bash行为不匹配



当我在bash中执行以下命令时,我会得到一个与我想要的正则表达式匹配的文件列表:

$> ls *-[0-9].jtl
benchmark-1422478133-1.jtl  benchmark-1422502883-4.jtl  benchmark-1422915207-2.jtl

然而,当我在鱼壳中运行相同的命令时,我会得到不同的结果:

$> ls *-[0-9].jtl
fish: No matches for wildcard '*-[0-9].jtl'.
ls *-[0-9].jtl
   ^

为什么?

Fish的文档并没有声称支持POSIX glob模式的全部功能。

引用文档:

通配符

如果参数中存在星号(*)或问号(?),fish会尝试将给定的参数与任何文件进行匹配,方法如下:

  • CCD_ 1可以匹配除CCD_ 2之外的任何单个字符
  • CCD_ 3可以匹配不包含CCD_ 4的任何字符串。这包括匹配一个空字符串
  • **匹配任何字符串。这包括匹配一个空字符串。该字符串可以包括/字符,但不需要

值得注意的是,没有提到角色类,因为fish不支持它们。

如果您希望globs保证支持所有POSIX(fnmatch)功能,请使用符合POSIX的或POSIX超集shell。

您还可以使用更多扩展工具unix find。它非常强大。

  • https://kb.iu.edu/d/admm
  • https://duckduckgo.com/?q=unix+查找

示例:使用正则表达式

find . -path '.*-[0-9].jtl' -not -path '.*-32.jtl'

Fish只需要引用"*.conf"就可以完成与bash *.conf相同的操作。

这是一篇较旧的文章,但我认为值得重新审视。在撰写本文时(2021年3月),文档明确表示支持通配符。

Fish支持熟悉的通配符*。列出所有JPEG文件:

> ls *.jpg
lena.jpg
meena.jpg
santa maria.jpg

您可以包括多个通配符:

> ls l*.p*
lena.png
lesson.pdf

特别强大的是递归通配符**,它递归搜索目录:

> ls /var/**.log
/var/log/system.log
/var/run/sntp.log

然而,我仍然经常遇到同样的问题

[/home/glass ]
><glass@rockpiX-Ubuntu> rm *.log.old
fish: No matches for wildcard “*.log.old”. See `help expand`.
rm *.log.old
   ^

在fish 3+中,您可以使用?0:

ls | string match -r --entire '-[0-9].jtl'

选项:

  • -r:正则表达式
  • --entire:返回整个匹配字符串

最新更新