Function Glob作为shell函数的参数

Function Glob作为shell函数的参数,function,shell,parameter-passing,zsh,Function,Shell,Parameter Passing,Zsh,我正在编写一个可重用函数,所以我需要参数尽可能灵活 考虑一个简单的例子: function testf(){ print ./*.$1 } 这很有效。例如,使用testf mp3时,它以数组形式列出以.mp3结尾的所有文件,从而使可以用于循环。但这种方式只允许我使用扩展名 因此,我尝试: function testf(){ print ./$1 } 但是,它不起作用。使用testf*.mp3,与在终端中使用print*.mp3不同,它只传递第一个匹配字符串,而不是整个数组 有

我正在编写一个可重用函数,所以我需要参数尽可能灵活

考虑一个简单的例子:

function testf(){
    print ./*.$1
}
这很有效。例如,使用
testf mp3
时,它以数组形式列出以
.mp3
结尾的所有文件,从而使
可以用于
循环。但这种方式只允许我使用扩展名

因此,我尝试:

function testf(){
    print ./$1
}
但是,它不起作用。使用
testf*.mp3
,与在终端中使用
print*.mp3
不同,它只传递第一个匹配字符串,而不是整个数组


有什么建议吗?

shell在启动命令之前执行几种类型的扩展。当你进入

testf*.mp3
shell将首先展开glob,并将每个文件名作为单独的参数传递给函数

您的函数可以如下所示:

function testf(){
    printf './%s\n' "$@"
}
列出数组中以.mp3结尾的所有文件。。。你的问题中没有涉及数组

但对于您的问题:首先,您希望向函数传递一个通配符模式,但这不是您实际要做的
testf*.mp3
在调用函数之前展开模式(此过程称为文件名生成),而您的
testf
仅获取文件列表作为参数。可以传递模式,但必须要求shell不要扩展模式:

testf '*.mp3'
在本例中,您的
$1
确实将包含字符串
*.mp3
。但是,您的
打印。/$1
仍不起作用。原因是文件名的生成发生在参数扩展之前(即,
$1
被包含的字符串替换的过程)。同样,您必须要求shell以另一种方式进行:

print ./${~1}

*.mp3
是一个glob,不是正则表达式。@Wiktor但是当使用
/0[3-6]*.mp3
时,它不应该是正则表达式?这取决于你认为
*
的作用。无论如何,这不是一个关于正则表达式的问题。
/0[3-6]*。mp3
既是一个合法的全局表达式,也是一个合法的正则表达式,但它们的含义不同。外壳会将其视为一个球体;如果它作为纯字符串传递(通过引用它来防止shell扩展),它将被视为接收它的程序所期望的任何内容。@chepner感谢您指出,我不知道
$@
会扩展到所有参数。是否可以使其忽略第一个参数而执行其余参数?标准方法是先执行
shift
first,然后放弃第一个参数
bash
允许您使用
“${@:1}”
作为替代方案,不修改
$@
的值。制作一个数组使其工作,谢谢!