Bash 参数替换:命令行与脚本

Bash 参数替换:命令行与脚本

我正在练习参数替换在bash中。

我编写了以下虚拟脚本:

#!/bin/bash

var1="/some/path/to/file/the_file.arbitrary.n.ext.0.random.ext"
var2="/some/path/to/file/the_file.arbitrary.n.ext.0.ext"

pattern='.[0-9]?(.random).ext'

echo "${pattern}"
echo "${var1/${pattern}/}"
echo "${var2/${pattern}/}"

基本上,该模式旨在去除文件名的最后部分。


执行虚拟脚本会导致:

~$ ./dummy.sh 
.[0-9]?(.random).ext
/some/path/to/file/the_file.arbitrary.n.ext.0.random.ext
/some/path/to/file/the_file.arbitrary.n.ext.0.ext

evaling 脚本的内容,或者等效地,在交互式 shell 中直接输入该命令序列,会产生:

~$ eval "$(cat dummy.sh)"
.[0-9]?(.random).ext
/some/path/to/file/the_file.arbitrary.n.ext
/some/path/to/file/the_file.arbitrary.n.ext

该模式'.[0-9]*.ext'有效,因此问题显然仅限于子字符串'?(.random)'。问题可能出在?,因为它是参数替换上下文中的保留字符。然而,如果这就是问题所在,我预计该模式在这两种情况下要么失败,要么成功。

可能明显的陷阱在哪里?

答案1

问题可能是extglobshell 选项是在交互式 shell 中设置的,而不是在脚本 shell 中设置的。

$ shopt -u extglob
$ echo "${var1/${pattern}/}"
/some/path/to/file/the_file.arbitrary.n.ext.0.random.ext
$ shopt -s extglob
$ echo "${var1/${pattern}/}"
/some/path/to/file/the_file.arbitrary.n.ext

因此,您可以尝试shopt -s extglob将其放在脚本中的 shebang 行之后。

来自Bash 参考手册

如果extglob使用内置命令启用了 shell 选项shopt,则可以识别几个扩展模式匹配运算符....可以使用以下一个或多个子模式形成复合模式:

?(PATTERN-LIST)
    匹配零次或一次出现的给定模式。

相关内容