如何将子目录中的所有文件递归移动到单个目录?


10

我试图将当前目录下的所有文件以及所有子目录收集到一个目录中。我正在尝试以下内容

find -type f -exec mv {} collection/{} \; 

上面的命令不起作用,因为第二个命令{}提供了完整路径,我如何收集所有文件?

Answers:


14

{}从中删除mvmv将忽略所有父目录,将其作为目标目录:

find -type f -exec mv {} collection/ \;

哦,我没有想到。谢谢:)
兔子兔子

正如我在回答问题时所说的那样,这可能是个坏主意。也许使用参数-maxdepth 1会有所帮助。
loevborg 2011年

想起来,似乎我读错了您的问题:)对不起。
loevborg 2011年

@loevborg:我现在为标题添加了“递归”。如果仍然有混淆,请对其进行编辑并加以改善:)
Lekensteyn 2011年

1
这个答案的更快变化是find -type f -print0|xargs -0r mv -it colection/
hildred

5

除了使用find(可以很好地完成工作)之外,您还可以使用外壳来达到此目的。

假设您要从$ PWD到$ DEST的所有文件。自然的尝试是:

mv $PWD/* $DEST

这是如何运作的?表达式“ $ PWD / *”扩展为该目录中所有文件的名称。这个外壳功能称为“ globbing”。的最后一个参数mv是目标目录。如果文件太多,则此操作将无效,因为命令行的长度受到限制。

但是该解决方案存在一个问题,即它省略了点文件-或名称以“。”开头的“隐藏”文件,文件和目录。为了解决这个问题,您必须告诉您的外壳在遍历时包含点文件。为此,请使用

shopt -s dotglob

使用时bashbash除非更改了默认值,否则您可能会使用)。在此Shell中,上述命令也适用于点文件。

顺便说zsh一句,在中,您可以选择根据情况选择此选项。为此,请放

setopt extendedglob

在你的.zshrc。那你可以用

mv $PWD/*(D) $DEST

移动所有文件,包括点文件。(“ D”的作用是暂时启用“ GLOB_DOTS”选项)。

现在,最初的问题是将所有常规文件(而非目录)从所有子目录及其子目录移动到单个目录。这可以通过以下方式完成zsh

mv $PWD/**/*(D.)

这里的表达式**/*使globeb递归地下降到子目录中。该D“也选择点文件;手段.的意思是‘只有选择正规的文件,不是目录’。


好吧,我也想递归到所有子目录,但是无论如何,还是要感谢信息的帮助,要经常遇到这种情况:)
Bunny Rabbit

实际上,find并不能解决所有问题,globbing将选择所有匹配项,不仅是文件,还包括目录。如果您担心性能,也可以使用:find -type f -exec mv -t collection/ {} +。请查阅手册页以了解其工作原理。
Lekensteyn 2011年

Lekensteyn,你是对的。现在,我已经理解了这个问题,因此我更新了答案。
loevborg 2011年

2
很棒的答案,太糟糕了,以至于与问题不是特别相关:)。
crazy2be 2011年
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.