这可能很简单,但我无法弄清楚。我有一个像这样的目录结构(dir2
在里面dir1
):
/dir1
/dir2
|
--- file1
|
--- file2
file1
以 get和file2
notdir1
的方式“展平”此目录结构的最佳方法是什么dir2
?
答案1
您可以使用 GNUfind
和 GNU来做到这一点mv
:
find /dir1 -mindepth 2 -type f -exec mv -t /dir1 -i '{}' +
基本上,如果它find
遍历整个目录树,并且对于-type f
不在顶级目录 ( ) 中的每个文件 ( -mindepth 2
),它会运行 amv
将其移动到您想要的目录 ( -exec mv … +
)。的参数-t
允许mv
您首先指定目标目录,这是必需的,因为+
的形式-exec
将所有源位置放在命令的末尾。在覆盖任何重复项之前,make-i
会询问;mv
您可以-f
在不询问的情况下覆盖它们(或-n
不询问或覆盖)。
正如 Stephane Chazelas 指出的那样,上述内容仅适用于 GNU 工具(这是 Linux 上的标准,但不适用于大多数其他系统)。下面的代码有点慢(因为它调用mv
多次),但更通用:
find /dir1 -mindepth 2 -type f -exec mv -i '{}' /dir1 ';'
POSIXly,传递多个参数,但使用sh
重新排序参数列表,mv
以便目标目录位于最后:
LC_ALL=C find /dir1 -path '/dir1/*/*' -type f -exec sh -c '
exec mv "$@" /dir1' sh {} +
答案2
在 zsh 中:
mv dir1/*/**/*(.D) dir1
**/
递归遍历子目录。这全局限定符 .
仅匹配常规文件,并D
确保包含点文件(默认情况下,名称以 a 开头的文件将从.
通配符匹配中排除)。之后要清理现在为空的目录,请运行rmdir dir1/**/*(/Dod)
--restricts /
todirectories,并od
首先对匹配深度进行排序,以便删除dir1/dir2/dir3
之前的dir1/dir2
.
如果文件名的总长度非常大,您可能会遇到命令行长度的限制。 Zsh 有内置的mv
和rmdir
不受此限制的影响:运行zmodload zsh/files
以启用它们。
仅使用 POSIX 工具:
find dir1 -type f -exec mv {} dir1 \;
find dir1 -depth -exec rmdir {} \;
或者(更快,因为它不必为每个文件运行单独的进程)
find dir1 -type f -exec sh -c 'mv "$@" dir1' _ {} +
find dir1 -depth -exec rmdir {} +
答案3
tar 和 zip 都能够合并然后剥离目录结构,因此我能够快速展平嵌套目录
tar -cvf all.tar *
然后将 all.tar 移动到新位置
tar -xvf all.tar --strip=4
答案4
尝试这样做:
cp /dir1/dir2/file{1,2} /another/place
file[0-9]*
或对于子目录中匹配的每个文件:
cp /dir1/dir2/file[0-9]* /another/place