【问题标题】:Ignore empty matches while glob expanding on bash for loop [duplicate]在 bash for loop 上扩展 glob 时忽略空匹配项 [重复]
【发布时间】:2016-06-03 19:56:56
【问题描述】:

我正在编写一个脚本来将文件(例如Dropbox Camera Uploads)移动到年份命名文件夹,如下所示:

#!/bin/bash
#
# Separate (camera) images on directory
# to year named folders.
#
# All files must be named as "yyyy-mm-dd HH:MM:SS.ext"
#
for img in *.{jpg,jpeg,png}; do
  year=${img:0:4}
  [ -d "$year" ] || mkdir "$year"
  mv -iv "$img" "$year/"
done

该脚本对匹配文件按预期工作,但是当没有任何具有某些扩展名的文件时,扩展为*.ex(前两个扩展名字符)。然后它会创建如下的空目录:

'*.jp'
'*.jp'
'*.pn'

我怎样才能忽略没有匹配的文件?

【问题讨论】:

    标签: bash glob


    【解决方案1】:

    您想要nullglob 选项;不匹配任何内容的模式将被忽略,而不是按字面意思处理。

    shopt -s nullglob
    for f in *.does_not_exist; do
        echo "This won't be reached"
    done
    

    【讨论】:

      【解决方案2】:

      您有两个主要选择。正如@chepner 建议的那样,一种是打开nullglob,这会使无与伦比的glob 扩展为null:

      shopt -s nullglob
      

      另一个是在对文件进行任何操作之前测试文件是否存在:

      for img in *.{jpg,jpeg,png}; do
        if [ -f "$img" ]; then   # not true for '*.jpg' etc
          year=${img:0:4}
          [ -d "$year" ] || mkdir "$year"
          mv -iv "$img" "$year/"
        fi
      done
      

      您也可以使用mkdir -p 并跳过-d 测试。

      【讨论】:

      • 是的,我会使用测试。但是 nullglob 选项看起来更干净。不确定我是否更安全。
      • 感谢-p 的提示。
      • @paulodiovani 主要区别在于nullglob 是特定于 bash 的,测试可移植到大多数 shell。
      【解决方案3】:

      你可以先检查文件是否存在,如果不存在则continue循环

      #!/bin/bash
      #
      # Separate (camera) images on directory
      # to year named folders.
      #
      # All files must be named as "yyyy-mm-dd HH:MM:SS.ext"
      #
      for img in *.{jpg,jpeg,png}; do
        [ ! -f "$img" ] && continue
        year=${img:0:4}
        [ -d "$year" ] || mkdir "$year"
        mv -iv "$img" "$year/"
      done
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-24
        • 2011-02-25
        相关资源
        最近更新 更多