删除中间文件夹

时间:2018-09-01 14:44:46

标签: bash file robocopy file-management

也许你们中的一个已经有类似的东西了?我试图在Windows上使用robocopy,但无济于事。我还尝试用 find 等在Linux上编写bash脚本,但是也放弃了它。^不幸的是,谷歌搜索也没有提供解决方案。我的私人照片库需要这个。

解决方案可以是基于Linux或Windows的,两者都很好。有任何想法吗?

我想摆脱数百个“中间文件夹”。

我将“中间文件夹”定义为一个文件夹,其中仅包含一个子文件夹。例子

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重命名为“文件夹2-文件夹3”,那将是更酷的选择,但是我猜我可以不用此功能。

我想你们当中的Linux专家中有一位很方便吗? ^^

非常感谢!

1 个答案:

答案 0 :(得分:4)

看看这段代码:

#!/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:打印以空字符\0分隔的目录(以正确处理文件名中可能的换行符)
  • 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