展平嵌套目录

tur*_*tle 91 directory cp recursive rename files

这可能很简单,但我无法弄清楚。我有一个这样的目录结构(dir2 在 dir1 中):

/dir1
    /dir2 
       |
        --- file1
       |
        --- file2
Run Code Online (Sandbox Code Playgroud)

以这样的方式“扁平化”这个导演结构的最佳方法是在 dir1 而不是 dir2 中获取 file1 和 file2。

der*_*ert 96

你可以用 GNUfind和 GNU做到这一点mv

find /dir1 -mindepth 2 -type f -exec mv -t /dir1 -i '{}' +
Run Code Online (Sandbox Code Playgroud)

基本上,如果find遍历整个目录树并且对于-type f不在顶级目录 ( -mindepth 2)中的每个文件( ) ,它会运行 amv将其移动到您想要的目录 ( ) 时,这种方法是有效的-exec mv … +。该-t给的说法mv,您可以先指定目标目录,这是必须的,因为+形式-exec将所有在命令结束的源位置。该-i品牌mv覆盖任何重复之前询问; 您可以-f在不询问的情况下替代覆盖它们(或-n不询问或覆盖)。

正如 Stephane Chazelas 指出的那样,以上仅适用于 GNU 工具(这是 Linux 上的标准,但不适用于大多数其他系统)。以下有点慢(因为它调用mv多次)但更通用:

find /dir1 -mindepth 2 -type f -exec mv -i '{}' /dir1 ';'
Run Code Online (Sandbox Code Playgroud)

  • 编辑为使用 `-exec +` 以便它不会执行大量的 `mv` 进程 (3认同)
  • @Random832 并且将再次恢复,因为 + 不起作用。`mv` 需要目的地作为最终参数,但 + 会将源作为最终参数。Find 甚至不会*接受*您将其更改为的语法(“find:缺少 \`-exec' 的参数”) (2认同)
  • @Random832,但我想 `mv` 有一个我们可以使用的 `-t`,所以我将其更改为那个。 (2认同)
  • 或者`find ./dir -mindepth 2 -type f -exec mv -f '{}' ./dir ';'` 如果覆盖重复项 (2认同)
  • @a--m `{}` 被 find 替换为文件名/路径。 (2认同)

Gil*_*il' 48

在 zsh 中:

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

**/递归遍历子目录。在预选赛水珠 .只匹配常规文件,并D点缀文件,确保包括(默认情况下,文件的名字开始与一个.被排除通配符匹配)。要在之后清理现在为空的目录,请运行rmdir dir1/**/*(/Dod)-/限制目录,并od首先对匹配深度进行排序,以便删除dir1/dir2/dir3before dir1/dir2

如果文件名的总长度非常大,您可能会遇到命令行长度的限制。岩组有内建mvrmdir其不受此限制:运行zmodload zsh/files启用它们。

仅使用 POSIX 工具:

find dir1 -type f -exec mv {} dir1 \;
find dir1 -depth -exec rmdir {} \;
Run Code Online (Sandbox Code Playgroud)

或(更快,因为它不必为每个文件运行单独的进程)

find dir1 -type f -exec sh -c 'mv "$@" dir1' _ {} +
find dir1 -depth -exec rmdir {} +
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案!尤其是简洁的 zsh 版本。 (2认同)

小智 8

tar 和 zip 都能够合并然后剥离目录结构,因此我能够使用以下命令快速展平嵌套目录

tar -cvf all.tar *

然后将 all.tar 移动到新位置

tar -xvf all.tar --strip=4


Gil*_*not 5

尝试这样做:

cp /dir1/dir2/file{1,2} /another/place
Run Code Online (Sandbox Code Playgroud)

file[0-9]*或对于子目录中匹配的每个文件:

cp /dir1/dir2/file[0-9]* /another/place
Run Code Online (Sandbox Code Playgroud)

请参阅http://mywiki.wooledge.org/glob


Yan*_*ves 5

扩展这个问题的流行答案,因为我有一个用例来展平包含同名文件的目录。

dir1/
??? dir2
?   ??? file
??? dir3
    ??? file
Run Code Online (Sandbox Code Playgroud)

在这种情况下,传递给-i( --interactive) 选项mv不会产生所需的结果来展平目录结构和处理名称冲突。所以它只是简单地替换为--backup=t(相当于--backup=numbered)。有关-b( --backup) 选项的更多文档,请访问https://www.gnu.org/software/coreutils/manual/coreutils.html#Backup-options

导致:

find dir1/ -mindepth 2 -type f -exec mv -t dir1/ --backup=t '{}' +
Run Code Online (Sandbox Code Playgroud)

其中产生:

dir1/
??? dir2
??? dir3
??? file
??? file.~1~
Run Code Online (Sandbox Code Playgroud)