删除中间文件夹

deleting intermediary folders

也许你们中的某个人手头有这样的东西?我尝试在 windows 上使用 robocopy 但无济于事。我还尝试用 find 等在 linux 中编写一个 bash 脚本...但也放弃了 ^^ Google 搜索带来的不幸的是也没有解决方案。我的私人照片库需要这个。

解决方案可以基于 linux 或 windows,两者都可以。有任何想法吗?

我想摆脱数百个'intermediary folders'。

我将 'intermediary folder' 定义为只包含一个子文件夹的文件夹。例子

folder 1
    file in folder 1
    folder 2            <-- 'intermediary folder: contains exactly one sub-folder, nothing else'
        folder 3
           file in folder 3

我想结束的是:

 folder 1
      file in folder 1
      folder 3
           file in folder 3

我不需要递归脚本(一次删除几层中间文件夹),我会 运行 几次。

如果脚本可以将上面示例中的文件夹 3 重命名为 'folder 2 - folder 3',那就更酷了,但我想我可以在没有这个功能的情况下生活。

我想你们中的一位 linux 专家有一个方便的衬垫吗? ^^

非常感谢!

看看这段代码:

#!/usr/bin/env bash

shopt -s nullglob
while IFS= read -rd '' dir; do
    f=("$dir"/*)
    if ((${#f[@]}==1)) && [[ -d $f ]]; then
        mv -t "${dir%/*}" "$f" || continue
        rm -r "$dir"
    fi  
done < <(find folder1 -depth -mindepth 1 -type d -print0)

解释:

  • shopt -s nullglob:允许不匹配任何文件的文件名模式扩展为空字符串
  • find ... -depth:使得find以深度优先的顺序遍历文件系统
  • find ... -mindepth 1:处理除起点外的所有目录
  • find ... -type d: 只查找目录
  • find ... -print0:打印由空字符分隔的目录 [=18=](以正确处理文件名中可能的换行符)
  • while IFS= read ...:遍历所有目录(find的输出)
  • f=("$dir"/*): 在当前处理的目录
  • 中创建一个包含所有文件的数组
  • ((${#f[@]}==1)) && [[ -d $f ]]:如果只有一个文件且是目录则为true
    • mv -t "${dir%/*}" "$f": 将唯一的子目录移动到上一级目录
    • mv ... || continue: 如果子目录已经存在于上面的目录中,mv 可能会失败。 || continue 忽略此类子目录
    • rm -r "$dir": 删除处理后的目录

测试运行:

$ tree folder1
folder1
├── file1
├── folder2
│   └── folder3
│       └── file3
├── folder4
│   ├── file4a
│   ├── file4b
│   └── file4c
└── folder5
    └── folder6
        ├── file6
        └── folder7
            └── folder8
                └── folder9
                    ├── dir9
                    └── file9
$ ./script
$ tree folder1
folder1
├── file1
├── folder3
│   └── file3
├── folder4
│   ├── file4a
│   ├── file4b
│   └── file4c
└── folder6
    ├── file6
    └── folder9
        ├── dir9
        └── file9