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



我有一些.zip文件与与.zip文件名称相似的目录。我正在尝试使用某种通配符将.zip文件移动到其相应的目录中。

#!/usr/bin/env bash    
find "/Volumes/volume1/test/" -type f -name "*.zip" -print0 |
while IFS= read -r -d $'' 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

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 只匹配目录;将该表达式的结果存储在数组中;并检查该数组的长度。
  • 因为如果不存在匹配项,glob 会扩展到自身(如果nullglob或修改 shell 行为的另一个标志不存在(,我们还在测试结果数组中的第一个条目是否实际存在。

最新更新