使用 zsh 时将正则表达式传递给命令

使用 zsh 时将正则表达式传递给命令

在 bash 中我可以执行以下操作:

apt install blabla*

但在 zsh 中我得到

zsh: no matches found: blabla*

除非当前目录下有一个叫blablabla的文件。

这也会导致删除文件时出现问题之内如果需要 sudo 访问权限才能写入文件夹,则无需删除文件夹本身。

如何让 zsh 将正则表达式传递给命令?

答案1

请注意,文件名通配模式不是正则表达式。他们是相似的但通配模式blabla*将匹配以 string 开头的名称blabla,而正则表达式blabla*将匹配包含子 string 的字符串blabl,可能后跟零个或多个a字符。

将字符串blabla*作为参数传递apt install给 shell,而不会尝试将其用作文件名通配模式,引用它:

apt install 'blabla*'

默认情况下, shellzsh具有NOMATCHshell 选项集,它对应failglobbash(不是在该 shell 中默认设置)。当通配模式与任何内容都不匹配时,这将使 shell 失败并显示诊断消息。您显然也可以关闭此 shell 选项(使用unsetopt NOMATCH或),但是在使用删除您无权访问的文件setopt NO_NOMATCH的情况下,这对您没有帮助。sudo

要扩展诸如 之类的文件名模式bla/*,需要一个 shell(该rm命令本身无法扩展 shell 通配模式,并且很少有命令可以,因此sudo rm -rf bla/*即使您阻止当前 shell 尝试扩展模式,也无法工作引用它)。由于您可能无权读取目录中的名称bla,因此该 shell 必须以以下用户身份执行:有权读取目录中的名称,例如root。我们可以使用 root 用户身份执行 shell sudo

要删除您无权访问的目录中的所有文件和目录,请使用sudo

sudo sh -c 'rm -rf directoryname/*'

请注意,这不会删除隐藏名称,为此,请使用类似

sudo bash -O dotglob -c 'rm -rf directoryname/*'

或者

sudo zsh -c 'rm -rf directoryname/*(D)'

或者

sudo find directoryname -mindepth 1 -delete

或者,使用标准find

sudo find directoryname -depth ! -path directoryname -exec rm -rf {} +

前三个命令依赖于 root 用户运行的sh -c,bash -czsh -cshell 执行的通配,而后两个命令根本不使用文件名通配。的变体find还支持删除包含数千个文件的目录(如果尝试通配,这可能会生成“参数列表太长”错误)。

如果您确实想删除,还有另一个选择全部目录的内容,就是简单地删除整个目录

sudo rm -rf directoryname

然后使用正确的所有权和权限重新创建它。

相关内容