我在与.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
答案 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会扩展为自身,我们还会测试是否第一个条目在结果数组中实际存在。