如果您认识到在形成新目录名称时,旧的基本目录将只是新目录名称中的一个 子字符串,那么这个过程并不太难。 Bash 提供了一个带有子字符串替换的参数扩展,它是为这个过程量身定做的。
本质上,您 find 源目录下的每个文件都带有 *.mkv 扩展名,您使用 带有子字符串替换的参数扩展 来形成包含目标目录的新完整文件名,(例如nffn="${ffn/$srcdir/$destdir}",其中ffn 是full-filename 的缩写,nffn 是new full-filename 的缩写)
使用包含更新路径的新完整文件名,只需在移动文件之前确保目标目录存在即可。 mkdir -p 在这里是完美的,因为它将创建完整路径,并且如果目录已经存在则不会抱怨。您只需使用 带有子字符串删除的参数扩展 将新目录与新的完整文件名隔离开以传递给mkdir -p,最后,检查mkdir -p 是否成功或处理错误,例如
## create new directory, handle error if create fails
mkdir -p "${nffn%/*}" || {
echo "error: creating '${nffn%/*}'" >&2
exit 1
}
将所有部分放在一起,您可以使用类似于以下的简短脚本执行您正在尝试的操作。
#!/bin/bash
## source and destination directories, file pattern
# (note: to change destdir, two arguments required
# to change patrn, three arguments required)
srcdir="${1:-/home/david/dev/src-c/tmp/debug/AAA}"
destdir="${2:-/home/david/dev/src-c/tmp/debug/BBB}"
patrn="${3:-*.mkv}"
while read -r ffn; do ## loop over each full-filename
nffn="${ffn/$srcdir/$destdir}" ## form new full-filename
## create new directory, handle error if create fails
mkdir -p "${nffn%/*}" || {
echo "error: creating '${nffn%/*}'" >&2
exit 1
}
mv "$ffn" "$nffn" ## move full-filename to new full-filename
touch "$ffn" ## touch full-filename for zero original
done < <(find "$srcdir" -name "$patrn")
(注意:您可以将目录和文件模式作为位置参数传递,但请注意,如果您传递超过1个,则必须传递每个必需的参数(或者您可以实现getotp))
初始目录 AAA 和 BBB
$ tree AAA
AAA
├── a.mkv
├── b.mkv
├── dir1
│ ├── a.mkv
│ └── b.mkv
├── dir2
│ ├── a.mkv
│ └── b.mkv
├── dir3
│ ├── a.mkv
│ └── b.mkv
└── dira
├── a.mkv
└── b.mkv
$ tree BBB
BBB [error opening dir]
最终目录 AAA 和 BBB
$ bash mvemptydir.sh
$ tree AAA
AAA
├── a.mkv
├── b.mkv
├── dir1
│ ├── a.mkv
│ └── b.mkv
├── dir2
│ ├── a.mkv
│ └── b.mkv
├── dir3
│ ├── a.mkv
│ └── b.mkv
└── dira
├── a.mkv
└── b.mkv
$ tree BBB
BBB
├── a.mkv
├── b.mkv
├── dir1
│ ├── a.mkv
│ └── b.mkv
├── dir2
│ ├── a.mkv
│ └── b.mkv
├── dir3
│ ├── a.mkv
│ └── b.mkv
└── dira
├── a.mkv
└── b.mkv
查看一下,如果您还有其他问题,请告诉我。