13

这是我制作的一些代码:)

@echo off
set source="R:\Contracts\"
set destination="R:\Contracts\Sites\"
ROBOCOPY %source% %destination% *.srt *.pdf *.mp4 *.jpg /COPYALL /R:0 /S
for /r %source in (*) do @copy "%destination" .

R:\Contracts\ 充满了其中包含文件的文件夹。

我想将所有内容复制到 R:\Contracts\Sites\ 并展平文件夹结构。

一切都复制得很好,还有文件夹结构。

谢谢

4

5 回答 5

24

您可以使用 PowerShell one liner 做到这一点。在此示例中,我从所有子文件夹中过滤掉所有扩展名为 .txt 的文件。然后将它们发送到 Copy-Item Cmdlet。

组合 Cmdlet Get-Childitem(简称 GCI)、-recurse 和 -filter,然后将结果通过管道传输到 Copy-Item Cmdlet。首先使用 -WhatIf 检查输出是否符合您的预期。

复制到另一个文件夹(使用 -WhatIf 并验证输出以在提交复制文件之前检查您的命令):

Get-Childitem -recurse R:\Contracts -filter *.txt | Copy-Item -Destination R:\Contracts\Sites -WhatIf

要按照您的要求执行多种文件类型,您只需运行多个命令,每个文件类型一个。

于 2015-02-12T21:34:29.457 回答
12

没有一个命令会为您扁平化层次结构;您将不得不使用多个命令。只需使用 FOR /R 遍历层次结构,再加上您选择的复制/移动命令(移动、复制、xcopy、robocopy),即可完成。因为您的目标位于源层次结构中,所以您需要一个 IF 来防止目标成为源。

在继续之前,您应该停下来想想如果相同的文件名出现在多个源文件夹中会发生什么。您的目标文件夹中只能有一个版本。你能保证没有重复的名字吗?如果不是,应该保留哪个文件?您如何构造命令以保留所需的文件?这种复杂性可能是为什么没有编写命令来简单地扁平化层次结构的原因。

这是与 FOR /R 解决方案集成的 ROBOCOPY 命令。

@echo off
set source="R:\Contracts"
set destination="R:\Contracts\Sites"

::Not sure if this is needed
::It guarantees you have a canonical path (standard form)
for %%F in (%destination%) do set destination="%%~fF"

for /r %source% %%F in (.) do if "%%~fF" neq %destination% ROBOCOPY "%%F" %destination% *.srt *.pdf *.mp4 *.jpg /COPYALL /R:0
于 2011-12-31T23:31:17.477 回答
1

我最近不得不解决这个问题,并且我想从层次结构移动到单个文件夹的许多文件彼此具有相同的名称,并且我仍然希望在不覆盖它们的情况下使层次结构变平。我所做的是编写一个移动文件的脚本,但使用名称中的旧层次结构路径重命名它, 例如:源文件:

C:\files\somefiles\file.txt

C:\文件\其他文件\文件.txt

目标是 C:\newdir\ 文件创建为

C:\newdir\somefiles-file.txt

C:\newdir\otherfiles-file.txt

这是代码,批处理文件 1 遍历文件,批处理文件 2 重命名并移动它们(如果您想保留源代码,也可以复制:

@echo off
for /r %%f in (*.*pr) do @renameandmovefilespart2.bat "%%f" "%%~ff" "%%~xf"

重命名和移动文件part2.bat

@echo off
Setlocal EnableDelayedExpansion
rem set the whole file path
set origWhole=%1
set origPathOnly=%2
set extension=%3
rem here you can set where the directory to hold the flattened hierarchy is
set destDir=c:\destinationDir\
rem  set the directory to do a string replace
rem make this the starting directory, that you dont want in the newly renamed files
set startingDir=C:\starting\directory\
set nothing=
set slash=\
rem here you can set what the character to represent the directory indicator \ in the new files 
set reaplcementDirectoryCharacter=--
set quote="
rem cut out the starting part of the directory
call set newname=%%origWhole:!startingDir!=!nothing!%%
rem replace slashes with new character
call set newname=%%newname:!slash!=!reaplcementDirectoryCharacter!%%
rem remove quotes
call set newname=%%newname:!quote!=!nothing!%%
rem @echo shortened: %newname%
rem @echo source path: %origPathOnly% newPath: %startingDir%
rem @echo extension: %extension%
rem rename the files
ren %origWhole% %newname%
rem prepare to move the file, clean up the source path
call set origPathOnly=%%origPathOnly:!quote!=!nothing!%%
move "%origPathOnly%%newname%" "%destDir%"
于 2014-09-12T09:45:35.983 回答
1

与之前的 Powershell 选项类似,我做了以下操作来展平一个多子目录的音乐文件夹:

#Get all files and not the directories
$files = Get-ChildItem -Path R:\Contracts -Recurse | Where {$_.PSIsContainer -eq $false}

#Copy items from sources to new destination
foreach ($file in $files){
    Copy-Item -Path $file.FullName -Destination R:\Contracts\Sites\$($file.Name)
}

带有-Recurse开关的Get-ChildItem将获得所有子文件夹和文件的列表。Where函数通过检查布尔 PIsContainer 属性来删除所有目录。在不剥离目录的情况下,将创建没有文件的子文件夹结构。此列表存储在$files变量中。

foreach函数遍历$files变量中的文件列表,并在$file变量中一次存储一项。Copy-Item函数然后使用来自 $file.FullName 的完整路径,然后将文件从 $file.Name 复制到具有相同名称的目标

于 2019-09-14T18:06:45.517 回答
0

有一个名为 Sweep.exe 的旧 PCMag 实用程序,它可以在当前目录和子目录中操作相同的命令。我不会将目标作为源目录的子目录。把目的地放在别处。

http://www.rarewares.org/files/case/Sweep.zip

cd c:\contracts sweep copy *.* c:\sites

这会将 c:\contracts 和下面的所有内容复制到 c:\sites

我使用类似的命令来展平目录的层次结构。

请注意重复项以及您希望如何处理它们。你想覆盖或处理不同的方式。

于 2015-08-22T22:10:09.483 回答