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

Bun*_*bit 10 command-line find

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

find -type f -exec mv {} collection/{} \; 
Run Code Online (Sandbox Code Playgroud)

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

Lek*_*eyn 14

删除{}from mvmv将其作为目标目录而忽略任何父目录:

find -type f -exec mv {} collection/ \;
Run Code Online (Sandbox Code Playgroud)


loe*_*org 5

除了使用find(它可以很好地完成工作)之外,您还可以为此使用 shell。

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

mv $PWD/* $DEST
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?表达式“$PWD/*”扩展为该目录中所有文件的名称。此外壳功能称为“通配”。的最后一个参数mv是目标目录。如果您有很多文件,这将不起作用,因为命令行的长度是有限的。

但该解决方案的问题在于它省略了点文件 - 或“隐藏”文件、名称以“.”开头的文件和目录。为了解决这个问题,你必须告诉你的 shell 在 globbing 时包含 dotfiles。为此,请使用

shopt -s dotglob
Run Code Online (Sandbox Code Playgroud)

使用时bashbash除非您更改了默认值,否则您可能会使用)。在这个 shell 中,上面的命令也适用于 dotfiles。

顺便说zsh一句,在 中,您可以根据具体情况选择此项。要做到这一点,把

setopt extendedglob
Run Code Online (Sandbox Code Playgroud)

在您的.zshrc. 然后你可以使用

mv $PWD/*(D) $DEST
Run Code Online (Sandbox Code Playgroud)

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

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

mv $PWD/**/*(D.)
Run Code Online (Sandbox Code Playgroud)

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

  • 很好的答案,太糟糕了,它与问题没有特别的关系:)。 (2认同)