我有一个脚本,它使用find
来查找与用户输入匹配的文件。 基本上,用户输入类似test*
的东西,它应该找到所有匹配的文件。
我遇到的问题是,如果当前目录中有一个与用户输入的文件名模式匹配的文件,它只会查找该文件。 也就是说,如果用户输入fred*
并且当前目录中有一个名为frederica
的文件,则脚本只会找到名为 frederica 的文件。 下面是问题的示例:
>ls
test1 test2 test3 test4 test5 words
>tmp()
> {
> my_file="$1"
> find . -iname "$my_file"
> }
>tmp test*
./test1
>
如果我输入tmp test*
,我希望它返回五个文件test1到test5。 相反,它只返回第一个。 此外,如果我搜索,比如说,/
,它仍然只会从每个目录中返回名为test1的文件。
当然,实际的脚本更复杂,我已经开发了一种涉及"通配符选项"的解决方法(例如,-w 1
表示前导和尾随星号等),但我真的希望能够让用户输入带有通配符的文件名。
提前致谢
当你以你的方式调用函数时,解释调用的 shell 会尝试查找匹配的文件(这是在进入函数之前完成的),并且可能会发生不同的事情:
-
如果 glob 失败并且设置了
failglob
shell 选项,则根本不会执行该函数。 由于默认的外壳选项,您可能没有看到这一点。 -
否则,如果 glob 失败并且设置了
nullglob
shell 选项,则 glob 的结果根本不是任何东西,并且不会将任何参数传递给您的函数。 你可能也没有经历过。 -
否则,如果 glob 失败并且未设置
failglob
shell 选项,则 glob 的结果就是 glob 表达式的任何内容,这被用作参数值。 然后,这个 glob 表达式按原样传递给find
,find
做你想要的,因为它在内部实现了通配。 你很幸运,它有效,但它有效。 -
glob 成功并生成一个文件列表,该文件用作函数的参数列表。 您的调用
find
使用$1
,因此仅考虑这些参数中的第一个,从而导致您不想要的结果。
双引号或单引号禁用通配。 因此,如果从脚本使用,则可以执行以下操作:
tmp "test*"
如果要从命令行使用此命令,则唯一的选择是完全禁用通配,set -f
,这很可能有缺点。
>test*
扩展到test1 test2 test3 test4 test5
。你只看$1
,即test1
。
尝试将其称为tmp 'test*'
。