2014-09-29 69 views
3

在此先感谢您的时间和帮助。在保留文件的同时用Bash删除文件结构中的级别

我有一个情况,我有一个DIR包含几十个子DIR,其中所有的子DIR只包含一个文件(出于某些错误的原因)。我试图将所有文件在DIR树中上移两级,同时以其他所有方式保留文件结构。这里是我的意思的例子:

|--- DIR.Main 
|--- |---DIR.Sub-A 
|--- |--- |--- File.Sub-A 
|--- |---DIR.Sub-B 
|--- |--- |--- File.Sub-B 
|--- |---DIR.Sub-C 
|--- |--- |--- File.Sub-C 
|-->Continue for approx. 50 DIR.Subs 

我不需要在文件结构中的DIR.Sub水平,并希望它看起来像这个:

|--- DIR.Main 
|--- |---File.Sub-A 
|--- |---File.Sub-B 
|--- |---File.Sub-C 

这里是什么复利问题,虽然:文件名不整洁和有序的逻辑与前面的例子中,而是被随意命名如下:

|--- DIR.Main 
|--- |---DIR.Sasjaljesea 
|--- |--- |--- File.Sasjalsaejesea.mpg 
|--- |---DIR.qwerqwerewqwer 
|--- |--- |--- File.qwerqweresezswqwer.mpg 
|--- |---DIR.xcbxcvxcvbxcvb 
|--- |--- |--- File.xcsfasdbxcvxcvbxcvb.mpg 
|-->ETC 

然而,救命之恩的是,在上述考试所有文件共享相同的文件类型(在这种情况下为mpg)。

我读过的MV,并在猛砸CP相关文件,并没有能够拿出一个办法做到这一点在一个没有通过手动输入所有的文件名。我还研究了Xrandr和类似命令的选项。我已经能够得出一个解决方案最接近的是这样的:

find /path/to/search -type f -iname "*.mp3" -exec mv {} path/to/music \; 

从这个答案摘自:Moving multiple files in subdirectories (and/or splitting strings by multichar delimeter) [bash]

在哪里我明明纠正-iname改为.mpg和DIR的适合我的情况。

当我做这个它没有找到的所有文件,并将它们转移到我想要的文件夹,但它并置的所有文件到一个不可读.MPG文件,而不是复制递归每个单独的文件,并保持文件结构,我想。我已经在上面的命令中用cp递归地研究了cp,但是这似乎什么也不做,即使当我作为SUDO执行时也是如此。 cp带有额外的问题,我不想复制文件,只需删除它们所包含的中间文件夹即可。

你可能已经想通了,我试图避免简单地使用Linux中的GUI和去猛砸路线,原因很明显,这将需要几个小时才能做到这一点的窗口管理器,而我敢肯定有是在几秒钟内在Bash中完成的一种方法。这是一项任务,在Linux文件管理器中通常需要几秒钟的时间,如果有人正在处理少于十几个文件夹和文件移动,但目前的情况是,几十个不必要的DIR包装只有一个文件。因此,我需要一个干净的Bash解决方案。

再次感谢您的帮助。这是几个星期来令我感到沮丧的问题。

我欢迎任何问题。

+0

对文件操作的模式问题,尤其是'DIR ...'图。继续发帖,祝你好运! – shellter 2014-09-29 03:33:26

回答

1

xargsmv一起使用可以解决这个问题。您应该从当前工作目录DIR.Main开始,并使用不同的目录将所有内容都移动到。它需要有所不同,因为否则你会最终得到与新文件和目录相匹配的(空的)原始目录。我们可以解决这个问题,但我认为没有必要。

find -maxdepth 2 -mindepth 2 | xargs -I '{}' mv '{}' <PATH_TO_NEW_LOCATION>/ 

find结果是,正是一层进一步进入目录树比当前目录下的所有文件和目录的列表。然后调用xargs将所有这些结果移到给定的位置。

我已经测试过它,但是您可能还想在将它用于实时数据之前对其进行测试,或者至少需要复制一份。

+0

由于某些原因,我必须给“其他”(创建和删除文件)的完全许可,否则我得到了“无法移动文件示例,权限被拒绝”。 - 甚至当我像SUDO一样跑步时。我不确定这是为什么,但一旦我给了新的权限,这解决了我的问题。非常感谢你。 – lawreaf 2014-09-29 06:56:55

+0

如果你把'sudo'放在这个命令的前面,那么它只会应用到'find'命令,而不是实际进行移动的'xargs'命令。很高兴你的工作虽然。 – gandaliter 2014-09-29 11:02:11

0

这应该是一样简单

shopt -s dotglob; mv -iv DIR.Main/*/* DIR.Main/ 

如果碰到ARG_MAX把它放在一个循环

shopt -s dotglob; for f in DIR.Main/*/*; do mv -iv "$f" DIR.Main/ 
相关问题