我正在练习参数替换在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
而eval
ing 脚本的内容,或者等效地,在交互式 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
问题可能是extglob
shell 选项是在交互式 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)
匹配零次或一次出现的给定模式。