使用 bash 脚本对下载文件夹进行排序

使用 bash 脚本对下载文件夹进行排序

我正在编写脚本以满足我自己的需求,在 bash 中对我的 Mac 上的下载文件夹进行排序。我传递给函数的参数是:源目录、目标目录和我想要移动的文件扩展名数组。我的问题是,当函数位于“find”行时,它只会复制一个具有该扩展名的文件,但是当我删除所有变量并直接输入参数时,它就可以正常工作。发生了什么?

 function moveFaster(){
   clear
    src=$1
    dst=$2
    typ=$3
    if [ ! -d $dst ]
      then
        mkdir $dst
      fi

    for i in "${typ[@]}"
      do
        find $src -name "${i}" -exec mv {} ${dst} \;
      done


  }

答案1

函数的每个参数都是标量,而你试图传递一个数组。当你写

a=(foo bar qux)
moveFaster "$src" "$dst" "${a[@]}"

然后 moveFaster 接收五个参数:$src$dstfoo和。如果你写bar,那么只有数组的第一个元素被传递给函数,因为它本身扩展为数组的第一个元素。此外,你对 的赋值使它成为一个标量变量。quxmoveFaster "$src" "$dst" "$a"$atyp

由于您要将单个数组传递给函数,因此您可以声明它由所有剩余的参数组成。

moveFaster () {
  src="$1"
  dst="$2"
  shift 2
  typ=("$@")
}

与此相关的是,如果涉及的任何文件名包含空格或通配符 ( ?*\[),您的脚本将失败。为了避免这种情况,请遵守以下简单的 shell 编程规则:总是用双引号括住变量替换(除非您理解为什么在特定情况下它们不能出现)。

function moveFaster(){
  src="$1"
  dst="$2"
  typ=("$@")
  if [ ! -d "$dst" ];  then mkdir -- "$dst"; fi
  for i in "${typ[@]}"; do
    find "$src" -name "${i}" -exec mv {} "${dst}" \;
  done
}

另外,如果您使用的是 bash 4 或更高版本,那么仅使用 bash 功能就可以相当轻松地完成此操作。该extglob选项允许扩展 glob 模式,例如@(PATTERN1|PATTERN2)。该globstar选项允许递归匹配子目录中**/PATTERN名称匹配的文件。PATTERN

shopt -s extglob globstar
mkdir -p /common/destination/directory
mv /path/to/source/**/@(*.txt|*.html|README) /common/destination/directory

相关内容