如何将递增目录中的文件合并到一个目录中

如何将递增目录中的文件合并到一个目录中

我有一个遵循这种模式的目录结构:

- 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定义为在创建目标的父目录后移动文件的函数。

相关内容