Bash 如何传递带有嵌入通配符的文件名来查找,而不限制在本地找到的文件?

Bash 如何传递带有嵌入通配符的文件名来查找,而不限制在本地找到的文件?,bash,shell,suse,Bash,Shell,Suse,我有一个脚本,它使用find查找与用户输入匹配的文件。基本上,用户输入类似于test*的内容,它应该会找到所有匹配的文件 我遇到的问题是,如果当前目录中有一个文件与用户输入的文件名模式匹配,它只会查找该文件。也就是说,如果用户输入fred*,并且当前目录中有一个名为frederica的文件,那么脚本只会找到名为frederica的文件。下面是一个问题示例: >ls test1 test2 test3 test4 test5 words >tmp() > { >

我有一个脚本,它使用
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的文件

当然,实际的脚本更复杂,我已经开发了一个包含“通配符选项”(例如,
-w1
表示前导和尾随星号等)的解决方案,但我真的希望能够让用户输入带有通配符的文件名


提前感谢

test*
扩展到
test1 test2 test3 test4 test5
。您只看到
$1
,即
test1


尝试将其称为
tmp'test*”
test*
扩展为
test1 test2 test3 test4 test5
。您只看到
$1
,即
test1


尝试将其调用为
tmp'test*”

当您以这种方式调用函数时,解释调用的shell会尝试查找匹配的文件(这是在进入函数之前完成的),可能会发生不同的情况:

  • 如果glob失败并且设置了
    failglob
    shell选项,则该功能将根本不执行。您可能没有看到这一点,因为默认的shell选项

  • 否则,如果glob失败并且设置了
    nullglob
    shell选项,那么glob的结果将是零,并且不会向函数传递任何参数。你可能也没有经历过

  • 否则,如果glob失败并且未设置
    failglob
    shell选项,则glob的结果与glob表达式的结果相同,并将其用作参数值。然后,这个glob表达式按原样传递给
    find
    ,并且
    find
    执行您想要的操作,因为它在内部实现了globbing。你很幸运,它起作用了,但它起作用了

  • glob成功并生成一个文件列表,该列表用作函数的参数列表。使用
    $1
    调用
    find
    ,因此只考虑这些参数中的第一个,从而得到您不想要的结果

双引号或单引号禁用全局引用。如果从脚本中使用,则可以执行以下操作:

tmp "test*"

如果您想从命令行使用此命令,您唯一的选择是使用
set-f
完全禁用globbing,这可能有很多缺点。

当您以这种方式调用函数时,解释调用的shell会尝试查找匹配的文件(这是在进入函数之前完成的),不同的事情会发生:

  • 如果glob失败并且设置了
    failglob
    shell选项,则该功能将根本不执行。您可能没有看到这一点,因为默认的shell选项

  • 否则,如果glob失败并且设置了
    nullglob
    shell选项,那么glob的结果将是零,并且不会向函数传递任何参数。你可能也没有经历过

  • 否则,如果glob失败并且未设置
    failglob
    shell选项,则glob的结果与glob表达式的结果相同,并将其用作参数值。然后,这个glob表达式按原样传递给
    find
    ,并且
    find
    执行您想要的操作,因为它在内部实现了globbing。你很幸运,它起作用了,但它起作用了

  • glob成功并生成一个文件列表,该列表用作函数的参数列表。使用
    $1
    调用
    find
    ,因此只考虑这些参数中的第一个,从而得到您不想要的结果

双引号或单引号禁用全局引用。如果从脚本中使用,则可以执行以下操作:

tmp "test*"

如果要从命令行使用此命令,您唯一的选择是使用
set-f
,完全禁用globbing,这很可能有缺点。

为什么不试试
“$my_file”
或者甚至只是
$my_file
,这似乎没有帮助——在find命令中的
$my_file
周围加上单引号会导致找不到任何内容,而没有引号会给出与双引号相同的结果。这与以下内容密切相关。为什么不这样做您尝试
'$my_file'
甚至只是
$my_file
似乎没有什么帮助--在find命令中的
$my_file
周围加上单引号会导致找不到任何内容,而没有引号会产生与双引号相同的结果。这与以下因素密切相关。这很有效,但这意味着训练用户在单引号内输入参数,我认为这是行不通的。但是我想您可能已经了解了一些事情,
test*
的扩展是在脚本中发生的(当它被分配到我的_文件时),还是在脚本开始之前的实际命令中发生的?也就是说,问题在于键入
tmp test*
实际上与键入
tmp test1 test1 test3 test4 test5
相同,因此脚本甚至从未看到通配符?这是一个shell问题?是的,如果要传递一个literal
*
来查找,您必须