【问题标题】:How to skip the for loop when there are no matching files?没有匹配的文件时如何跳过for循环?
【发布时间】:2014-12-03 01:09:43
【问题描述】:

当我遍历所有以foo 开头的文件时,我会这样做

for f in foo* ; do echo "result = $f" ; done

问题是当 没有文件foo 开头时,我得到:

result = foo*

意味着循环执行一次,即使没有以foo开头的文件。

这怎么可能?如何循环遍历所有文件(如果没有文件则根本不循环)?

【问题讨论】:

标签: bash for-loop wildcard shopt


【解决方案1】:

你可以通过设置nullglob来阻止这种行为:

shopt -s nullglob

来自链接页面:

nullglob 是一个修改 [[glob]] 扩展的 Bash shell 选项 使得不匹配文件的模式扩展到零参数, 而不是自己。

您可以使用-u 删除此设置(未设置,而s 用于设置):

shopt -u nullglob

测试

$ touch foo1 foo2 foo3
$ for file in foo*; do echo "$file"; done
foo1
foo2
foo3
$ rm foo*

让我们看看:

$ for file in foo*; do echo "$file"; done
foo*

设置nullglob:

$ shopt -s nullglob
$ for file in foo*; do echo "$file"; done
$

然后我们禁用该行为:

$ shopt -u nullglob
$ for file in foo*; do echo "$file"; done
foo*

【讨论】:

    【解决方案2】:

    执行此操作的标准方法(如果您不能或不想使用nullglob)是简单地检查文件是否存在。

    for file in foo*; do
        [ -f "$file" ] || continue
        ...
    done
    

    检查$file 的每个值的开销是必要的,因为如果$file 扩展为foo*,您还不知道是否真的存在一个名为foo* 的文件(因为它匹配模式)或者如果模式无法匹配并扩展到自身。当然,使用nullglob 可以消除这种歧义,因为失败的扩展不会产生任何参数,并且循环本身也不会执行主体。

    【讨论】:

      猜你喜欢
      • 2013-02-07
      • 2014-07-07
      • 1970-01-01
      • 2019-04-14
      • 2019-08-20
      • 2012-01-30
      • 2011-12-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多