我有一个遵循这种模式的目录结构:
- Dir 01 (Disc 1) \
- Dir 01 (Disc 1).iso
- Dir 01 (Disc 2) \
- Dir 01 (Disc 2).iso
- Dir 01 (Disc 3) \
- Dir 01 (Disc 3).iso
- Dir 02 (Disc 1) \
- Dir 02 (Disc 1).iso
- Dir 02 (Disc 2) \
- Dir 02 (Disc 2).iso
- Dir 02 (Disc 1) (A) \
- Dir 02 (Disc 1) (A).iso
- Dir 02 (Disc 2) (A) \
- Dir 02 (Disc 2) (A).iso
我的目标是最终得到这样的结构:
- Dir 01 \
- Dir 01 (Disc 1).iso
- Dir 01 (Disc 2).iso
- Dir 01 (Disc 3).iso
- Dir 02 \
- Dir 02 (Disc 1).iso
- Dir 02 (Disc 2).iso
- Dir 02 (A) \
- Dir 02 (Disc 1) (A).iso
- Dir 02 (Disc 2) (A).iso
我知道必须有一种方法来循环这些目录,匹配文件名并将所有内容移动到位,但我无法理解如何编写脚本。任何指示将不胜感激。
答案1
鉴于您指定了所需的树结构,我将遵守它,但我无法强调不惜一切代价尝试避免目录和文件名中出现空格的重要性。如果您不需要间距,并且也可以在其位置使用“_”,请告诉我,我将提供更新的树结构。
初始树:
tree
.
├── Dir 01 (Disc 1)
│ └── Dir 01 (Disc 1).iso
├── Dir 01 (Disc 2)
│ └── Dir 01 (Disc 2).iso
├── Dir 01 (Disc 3)
│ └── Dir 01 (Disc 3).iso
├── Dir 02 (Disc 1)
│ └── Dir 02 (Disc 1).iso
├── Dir 02 (Disc 1) (A)
│ └── Dir 02 (Disc 1) (A).iso
├── Dir 02 (Disc 2)
│ └── Dir 02 (Disc 2).iso
└── Dir 02 (Disc 2) (A)
└── Dir 02 (Disc 2) (A).iso
8 directories, 7 files
重组它的命令 - 您可以留下注释,但请确保将其复制粘贴为一个命令。
find . -type f -iname '*iso' -exec bash -c '
var="$1" ; # found filename variable
bad_dir=$(dirname "$var" | grep -i "disc"); # old directory name variable
good_dir=$(echo "$bad_dir" | cut -d" " -f1,2,5- ) ; # Only acts on dirnames with "disc"
if [[ -n $good_dir ]] ; then
mkdir -p "$good_dir" ; # creates new proper dir
mv "$var" "$good_dir" ; # mv file to new dir
rmdir "$bad_dir" # removes old bad dir
fi
' bash {} \;
测试新的目录树结构:
tree .
.
├── Dir 01
│ ├── Dir 01 (Disc 1).iso
│ ├── Dir 01 (Disc 2).iso
│ └── Dir 01 (Disc 3).iso
├── Dir 02
│ ├── Dir 02 (Disc 1).iso
│ └── Dir 02 (Disc 2).iso
└── Dir 02 (A)
├── Dir 02 (Disc 1) (A).iso
└── Dir 02 (Disc 2) (A).iso
4 directories, 7 files
笔记:我添加了一项检查以确保重新运行该命令不会破坏当前结构。此外,上述内容甚至适用于更复杂的文件和目录名称,例如:
├── Dir 01 (Disc 3) (A) (B) (C)
└── Dir 01 (Disc 3) (A) (B) (C).iso
├── Dir 02 (Disc 1) (A) (B)
└── Dir 02 (Disc 1) (A) (B).iso
将重组为:
├── Dir 01 (A) (B) (C)
│ └── Dir 01 (Disc 3) (A) (B) (C).iso
└── Dir 02 (A) (B)
└── Dir 02 (Disc 1) (A) (B).iso
答案2
和zsh
:
autoload -U zmv
mkmv() { mkdir -p -- $2:h && mv -- "$@"; }
zmv -P mkmv -n '(*) [(]Disc <->[)](*)/(*.iso)' '$1$2/$3'
(在哪里-n
进行空运行以显示会发生什么)。
这给出:
mkmv 'Dir 01 (Disc 1)/Dir 01 (Disc 1).iso' 'Dir 01/Dir 01 (Disc 1).iso'
mkmv 'Dir 01 (Disc 2)/Dir 01 (Disc 2).iso' 'Dir 01/Dir 01 (Disc 2).iso'
mkmv 'Dir 01 (Disc 3)/Dir 01 (Disc 3).iso' 'Dir 01/Dir 01 (Disc 3).iso'
mkmv 'Dir 02 (Disc 1) (A)/Dir 02 (Disc 1) (A).iso' 'Dir 02 (A)/Dir 02 (Disc 1) (A).iso'
mkmv 'Dir 02 (Disc 1)/Dir 02 (Disc 1).iso' 'Dir 02/Dir 02 (Disc 1).iso'
mkmv 'Dir 02 (Disc 2) (A)/Dir 02 (Disc 2) (A).iso' 'Dir 02 (A)/Dir 02 (Disc 2) (A).iso'
mkmv 'Dir 02 (Disc 2)/Dir 02 (Disc 2).iso' 'Dir 02/Dir 02 (Disc 2).iso'
前面已将Wheremkmv
定义为在创建目标的父目录后移动文件的函数。