删除中间文件夹

问题描述 投票:0回答:1

也许你们其中一个人已经手头有这样的东西吗?我试图在Windows上使用robocopy,但无济于事。我也尝试在linux中使用find等编写一个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专家有一个方便的用途吗? ^^

非常感谢你!

bash file robocopy file-management
1个回答
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
© www.soinside.com 2019 - 2024. All rights reserved.