如何从递归目录中提取专门命名的文件夹,然后删除其他文件夹?


10

我有从解压缩zip文件获得的这种目录树:

x-> y-> z-> 运行 ->文件和目录

因此,有4个目录,其中3个没有文件(x,y,z),仅包含1个子目录,还有一个我感兴趣的目录,名为“ run ”。

我想将“运行”目录本身(包括其中的所有内容)移动到我解压缩的“根”位置(即“ x”所在的位置,但不在“ x”内部)。

假设:存在一个名为“ run”的文件夹,但我不知道要进入“ cd”目录必须有多少个目录(可以是3(x,y,z),可以是10个或更多)。也是未知的,不必是x,y,z等)。

我该怎么做?我尝试了这个问题的许多变体,但都失败了。


1
恐怕图片不是很清楚,不。请不要发布文字的屏幕截图。而是直接将文本粘贴到您的问题中,然后使用格式设置工具。我什至无法阅读您图片中的目录名称。我所看到的只是模糊的蓝色模糊。
terdon

Answers:


14

关于什么

  find . -type d -name run -exec mv {} /path/to/X \;

哪里

  • / path / to / X是您的目标目录
  • 您从同一地方开始。
  • 然后使用其他答案删除空目录。

(附带说明--junk-paths,在压缩或解压缩时,zip中都有一个选项)


7

我会bash使用来完成此操作globstar。如中所述man bash

globstar
      If set, the pattern ** used in a pathname expansion con‐
      text will match all files and zero or  more  directories
      and  subdirectories.  If the pattern is followed by a /,
      only directories and subdirectories match.

因此,要将目录run移到顶层目录x,然后删除其余目录,可以执行以下操作:

shopt -s globstar; mv x/**/run/ x/  && find x/ -type d -empty -delete

shopt命令启用该globstar选项。在mv x/**/run/ x/将命名任何子目录移动run(注意,如果只有一个这仅适用run目录)xfind将删除任何空目录。

如果愿意,您可以使用扩展的glob在shell中完成整个操作,但是我更喜欢使用安全网,find -empty以确保不会删除任何非空目录。如果您不在乎,可以使用:

shopt -s globstar; shopt -s extglob; mv x/**/run/ x/ && rm -rf x/!(run)

6

绝对更冗长,但一步一步即可完成工作:

假设您已安装python

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for root, dirs, files in os.walk(dr):
    # find your folder "run"
    for pth in [d for d in dirs if d == sys.argv[2]]:
        # move the folder to the root directory
        shutil.move(os.path.join(root, pth), os.path.join(dr, pth))
        # remove the folder (top of the tree) from the directory
        shutil.rmtree(os.path.join(dr, root.replace(dr, "").split("/")[1]))

如何使用

  1. 将脚本复制到一个空文件中,另存为 get_folder.py
  2. 使用根目录(包含解压缩的内容)和要“举升”的文件夹名称作为参数运行它:

    python3 /full/path/to/get_folder.py /full/path/to/folder_containing_unzipped_dir run
    

并完成:

在此处输入图片说明

在此处输入图片说明


这是一个非常有趣的解决方案,但出于各种原因,我不愿使用任何python脚本。谢谢!
Idos

没问题。也许对其他人有用。好奇为什么呢?我很确定许多应用程序已经在使用python。
Jacob Vlijm '17

主要是因为将.py文件放置在任何地方都是有问题的,因为我必须假设它将与运行我的脚本的每台Linux机器都位于同一位置(并且我的脚本可以在许多平台上运行)。
Idos

@Idos很好奇,哪个平台?Python非常普遍。我不认为它默认安装在Mac OS X上,但是大多数Linux发行版都安装了它
Sergiy Kolodyazhnyy

4

Perl解决方案

#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
use File::Copy::Recursive qw(dirmove);

my @wanted;
find(sub{ -d $_ && $_ eq "run" && push @wanted,$File::Find::name}, $ARGV[0]);
dirmove("$wanted[0]","./run");

它的工作方式很简单:find()子例程将递归遍历给定的目录树,找到名称为该目录的目录run并将其推入所需文件名数组。在这种情况下,我们假设列表中应该只有一个文件,因此,命令完成后,我们dirmove()将从File::Copy::Recursive模块中使用该文件,并将其移动到从中调用脚本的当前工作目录。因此,在您的情况下,您可以从父目录到调用它x

原始目录树:

$ tree                                                                                                                   
.
└── levelone
    └── leveltwo
        └── levelthree
            └── run
                ├── file1
                ├── file2
                └── file3

结果:

$ ~/find_dir.pl .  
$ tree 
.
├── levelone
│   └── leveltwo
│       └── levelthree
└── run
    ├── file1
    ├── file2
    └── file3
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.