Bash将文件移动到通配符目标

时间:2017-07-11 16:54:36

标签: bash grep

我在与.zip文件名称相同的目录所在的目录中有一些.zip个文件。我试图通过使用某种通配符将.zip文件移动到相应的目录中。

#!/usr/bin/env bash    
find "/Volumes/volume1/test/" -type f -name "*.zip" -print0 |
  while IFS= read -r -d $'\0' FILE; do
  ZIP="${FILE%.*}"
  echo $ZIP
  MATCH=${ZIP::${#ZIP}/3+${#ZIP}/2}
  echo ${MATCH##*/}
  mv "$FILE" "$(ls -l|grep "^d.*${MATCH##*/}")"
done

但是grep $MATCH中包含的空格存在问题。我不知道如何将文件移动到目标名称中带有通配符的目录。

示例目录:

drwxrwxrwx 1 username staff 264 Jul 10 22:43 [test]Peter Jackson - This is a test dir[29.06.17][1080]{username}

示例.zip

-rw-rw-rw- 1 username staff 13956939 Jul 10 22:58 [test]Peter Jackson - This is a test dir[29.06.17][Hi-Res].zip

1 个答案:

答案 0 :(得分:1)

while IFS= read -r -d '' file; do
  zip="${file%.*}"
  match=${zip::${#zip}/3+${#zip}/2}
  candidate_dirs=( "$match"*/ )
  if ! [[ -d "${candidate_dirs[0]}" ]]; then
    echo "No candidate directories (starting with $match) found" >&2
  elif (( ${#candidate_dirs[@]} != 1 )); then
    echo "Exactly one candidate directory must exist; found ${#candidate_dirs[@]}" >&2
  else
    # emit a correctly escaped, eval-able command. Remove the printf '%q ' to actually mv
    printf '%q ' mv -- "$file" "${candidate_dirs[0]}" && printf '\n'
  fi
done < <(find "/Volumes/volume1/test/" -type f -name "*.zip" -print0)

注意:

  • 我们将while循环移动到主shell中并将find命令放入进程替换中以避免BashFAQ #24中描述的问题。
  • 我们使用以/结尾的glob表达式强制我们的glob只匹配目录;将该表达式的结果存储在数组中;并检查该数组的长度。
  • 因为如果不存在匹配(如果nullglob或修改shell的行为的另一个标志不存在),则glob会扩展为自身,我们还会测试是否第一个条目在结果数组中实际存在。