我有这样的目录树,是通过解压缩 zip 文件获得的:
x -> y -> z ->跑步-> 这里是文件和目录
所以有4个目录,其中3个是空的文件(x,y,z)并且只包含1个子目录,并且有一个我感兴趣的目录,名为“跑步”。
我想将“run”目录本身(包括其中的所有内容)移动到我解压缩的“root”位置(即“x”所在的位置,但不在“x”内)。
假设:有存在一个名为“run”的文件夹,但我不知道需要“cd”多少个目录才能到达它(可能是 3 (x,y,z),可能是 10 或更多。名称也是未知的,并且不必是 x、y、z 等)。
我怎样才能做到这一点?我尝试了很多变体这个问题但他们都失败了。
答案1
关于什么
find . -type d -name run -exec mv {} /path/to/X \;
在哪里
- /path/to/X 是您的目标目录
- 你从同一个地方开始。
- 然后使用其他答案删除空目录。
(顺便说一句--junk-paths
,在压缩或解压缩时有一个 zip 选项)
答案2
我会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
目录时才有效)移动到,x
并find
删除所有空目录。
如果您愿意,您可以使用扩展的通配符在 shell 中完成整个操作,但我更喜欢find -empty
确保不会删除非空目录的安全网。如果你不关心这个,你可以使用:
shopt -s globstar; shopt -s extglob; mv x/**/run/ x/ && rm -rf x/!(run)
答案3
肯定更详细,但一步完成工作:
假设你已经安装了 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]))
如何使用
- 将脚本复制到一个空文件中,另存为
get_folder.py
使用根目录(包含解压的内容)和要“lift”的文件夹名称作为参数运行它:
python3 /full/path/to/get_folder.py /full/path/to/folder_containing_unzipped_dir run
就这样完成了:
答案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()
fromFile::Copy::Recursive
模块,并将其移动到调用脚本的当前工作目录。因此,在您的情况下,您可以将其从父目录调用到x
.
原始目录树:
$ tree
.
└── levelone
└── leveltwo
└── levelthree
└── run
├── file1
├── file2
└── file3
结果:
$ ~/find_dir.pl .
$ tree
.
├── levelone
│ └── leveltwo
│ └── levelthree
└── run
├── file1
├── file2
└── file3