展平目录结构


15

我的文件夹中有一堆文件夹。像这样

Root Folder
    -- Folder 1
    -- Folder 2
    -- Folder 3
    -- Folder 4

我要折叠所有文件夹,以便文件夹1,文件夹2,文件夹3,...文件夹n下的所有文件都位于根文件夹下。

在Windows中最快的方法是什么?


5
这取决于您要如何处理重复的文件名?
Mark Allen

Answers:


19

没有理由使用特殊工具甚至脚本。只需在资源管理器中使用搜索功能。

  1. 在资源管理器中打开要展平的文件夹。
  2. 创建一个新文件夹,选择所有文件(而不是文件夹),然后将它们拖到该文件夹​​中(这将避免获得这些文件的两个副本。)
  3. 在搜索框中(地址栏右侧的一个),输入*并按Enter。
  4. 列表填充后,右键单击并选择所有,然后右键单击并剪切。
  5. 按返回按钮返回到原始文件夹,然后右键单击并粘贴。
  6. 如果您有重复的名称,系统将提示您如何处理。为您的用例选择最合适的选项。(我认为这将同时复制两个文件。)为避免再次出现提示,请确保将其应用于所有文件,并勾选底部的复选框。
  7. 选择所有文件夹,通过查看有关所选文件数的弹出窗口来确保它们为空,然后将其删除。

如果您希望有一个脚本,这样就可以启动它而忘了它,那也可以做到。替换命令mv *\* .非常简单(for /r %f in (*.*) do @move "%~f" .),但我确定您希望处理重复项,而不必像@Nicole Hamilton的回答那样将其留在后面。在重复的文件名后加上数字可能是最简单的方法。

将以下批处理文件复制并粘贴到记事本中,并将其另存为“ flatten.cmd”(包括引号):

@echo off
cd "%~1"
md tempryfolder
move *.* tempryfolder
for /r %%f in ("*.*") do call :START "%%~f"
for /r /d %%f in (*.*) do rd "%%~f" 
GOTO :EOF
:START
setlocal
If exist "%~n1%~x1" set /a num=2
:LOOP
If exist "%~n1%num%%~x1" (
    set /a num+=1
    goto loop
)
move "%~1" "%~n1%num%%~x1"

要使用该脚本,只需将您想要展平的文件夹拖到其顶部即可。


1
类似但更容易理解:superuser.com/a/523854/433830
aparente001 '18

注意:此脚本实质上是叉子炸弹。我在具有数千个子目录和数万个子文件的文件夹中使用它,并且内存占用量正在缓慢增加。我认为我不会遇到OOM问题,但是要记住这一点。
Nzall

@Nzall我完全相信它可以做到这一点,但是我会怪微软,而不是我的代码。我要做的就是多次在批处理文件中调用一个子例程。而且我一次不会运行多个进程:每个子例程一直运行到完成为止,一次只运行一个进程。我们正在谈论使用多少内存?
凌晨

@trlkly尽管我确实有大量的文件夹和子文件夹,大约有75,000个文件和数千个文件夹,但它最多可以达到2 GB。几分钟后,它又下降到大约8-900 MB。虽然有大量重复文件。我整理了一个7500个文件的Javascript库的12个副本,因此可以测试某些软件如何处理包含成千上万个文件的文件夹。
Nzall

@Nzall对我来说真是不可思议。该脚本不执行任何操作。这是一个子例程,它重复使用单个变量来递增文件。我可能要问什么可能导致SO上如此大的内存使用或其他原因。
trlkly

9

您可以通过以下方式在Windows资源管理器中进行展平:浏览到要展平的文件夹,然后搜索System.Kind:<>folder以从结果中排除文件夹。

然后,您可以使用CTRL + A选择所有文件,然后将其复制并粘贴到新文件夹中。请注意,Windows资源管理器将询问您如何处理重复的文件名。

在此处输入图片说明


1
请注意,要执行此操作,您需要在相应的本地化翻译中键入“ folder”(例如,意大利语为System.Kind:<>cartella
JohnKiller 18'Oct

0

使用Unix shell,这种事情很容易。这是您可以使用我自己的Hamilton C shell(包括免费版本)进行的操作。您可以使用Cygwin bash进行非常相似的操作。

mv *\* .

如果您的目录确实很大,则可能通配符太长,导致Windows无法传递给子进程的命令行。(Windows CreateProcess调用将参数列表限制为32K Unicode字符。)但是C shell内部没有限制,因此您可以通过以下方式遍历整个列表:

foreach i ( *\* )
   mv $i .
end

上面@MarkAllen的观点,这种假设没有重复的名称。如果存在,列表中的较新副本将覆盖较旧的副本。如果这是一个问题,则可以遍历文件,mv仅在不覆盖的情况下对其进行“访问”。该:t操作员是尾操作符。该-e运营商的文件存在测试

foreach i ( *\* )
   if ( -e $i:t ) then
      echo -2 $i not moved because it already exists
   else
      mv $i .
   end
end

这仍然留下空目录,清空它们后,您可能不想使用这些目录。如果重要的话,那可能是下一次迭代。


使用cygwin> mv *。mv:无法统计`* ':没有这样的文件或目录
2013年

在Cygwin中bashmv */* .为我工作。
妮可·汉密尔顿

3
有些人对UNIX的看法如此固定……如果您真的想在Windows 7中进行脚本编写,则有PowerShell,您不需要像Cygwin这样的虚假bash模拟器。

您甚至不需要PowerShell。常规命令行仍然存在,并且可以执行相同的操作。请参阅下面的答案。
tlkly 2014年
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.