如何移动某些特定文件夹并保持预定义的目录结构?

如何移动某些特定文件夹并保持预定义的目录结构?

我有一个包含大约 7k 个文件夹的目录。这些文件夹是从 zip 中提取的,其中一些提取是使用 Python 脚本完成的。其中一些文件夹的提取方式如下

             Main Dir
                |
         ---------------
        |               |
      fold1            fold2
        |               |
      ------         -------
    |        |          |
  .pngs   .txts       fold2
                        |
                     -------
                    |       |
                  .pngs    .txts

要求是将fold2文件夹类别移动到与包含数据的文件夹类似的目录结构中,fold1而不是另一个包含数据的同名文件夹。

我如何使用 bash 或命令行来做到这一点,以便我拥有类似于 的同构结构中的所有 7k 文件夹fold1

答案1

以下脚本将在当前工作目录中搜索表单的路径a/B/B/c并将其压缩为a/B/c.这也会压缩a/B/B/B/B/ca/B/ca/B/B/c/D/D/ea/B/c/D/e

您需要 GNUfind来使用该选项和支持-regextype的实现。如果您没有这些,请查看脚本末尾的不安全 posix 版本。mv-n

shopt -s dotglob failglob
find . -depth -regextype egrep -type d -regex '.*/([^/]*)/\1' -print0 |
while IFS= read -r -d '' path; do
  mv -n -t "$path/.." "$path"/* &&
  rmdir "$path"
done

支持任意路径名(空格、特殊符号*,甚至换行符)。

该命令确保不是覆盖或删除任何文件。在左树中的情况下,必须保留重复的子目录。您将收到错误消息rmdir: failed to remove './A/A'。结果如右图所示。

. (before)               . (after)
└── A                    └── A
    ├── someFile             ├── someFile
    ├── collision            ├── collision
    └── A                    ├── anotherFile
        ├── collision        └── A
        └── anotherFile          └── collision

隐藏文件也会被复制。

错误的 Posix 版本

该脚本的一个更可移植的版本无法处理路径内的换行符,可能会在如上所示的情况下覆盖文件,并且无法移动隐藏文件(如果内部有隐藏文件,则保留子目录)。

find . -depth -type d | grep -E -x '.*/([^/]*)/\1' |
while IFS= read -r path; do
  mv "$path"/* "$path/.." &&
  rmdir "$path"
done

答案2

不确定这是否是您所需要的,但是...

mv /maindir/fold2/ /maindir/renamed/
mv /maindir/renamed/fold2/ /maindir/fold2/

然后,重命名应该是空的,删除它。

或者这也应该可以完成这项工作

mv maindir/fold2/fold2/{*,.*} maindir/fold2/

然后/maindir/fold2/fold2/应该是空的

相关内容