如何复制目录结构,但只包括某些文件(使用 Windows 批处理文件)

正如标题所说,如何递归地复制目录结构,但只包含一些文件。例如,给出了以下目录结构:

folder1
folder2
folder3
data.zip
info.txt
abc.xyz
folder4
folder5
data.zip
somefile.exe
someotherfile.dll

文件 Data.zipInfo.txt可以出现在目录结构中的任何位置。如何复制完整的目录结构,但只包含名为 data.zip 和 info.txt 的文件(应忽略所有其他文件) ?

The resulting directory structure should look like this:

copy_of_folder1
folder2
folder3
data.zip
info.txt
folder4
folder5
data.zip
231677 次浏览

你没有提到它是否必须是批处理的,但是如果你可以使用 ROBOCOPY,试试这个:

ROBOCOPY C:\Source C:\Destination data.zip info.txt /E

编辑: 将 /S参数更改为 /E以包含空文件夹。

XCOPY /S folder1\data.zip copy_of_folder1
XCOPY /S folder1\info.txt copy_of_folder1

编辑: 如果你想保留空文件夹(在重读你的文章时,你似乎是这样做的) ,请使用/E 代替/S。

这只是两个简单的命令,但是我不推荐这样做,除非您不需要复制的文件很小。这是因为这将复制所有文件,然后删除不需要的文件的副本。

xcopy /E /I folder1 copy_of_folder1
for /F "tokens=1 delims=" %i in ('dir /B /S /A:-D copy_of_files ^| find /V "info.txt" ^| find /V "data.zip"') do del /Q "%i"

Sure, the second command is kind of long, but it works!

此外,这种方法不需要您下载和安装任何第三方工具(Windows2000 + BATCH 有足够的命令来实现这一点)。

与 Paulius 的解决方案类似,但是你不关心的文件不会被复制然后删除:

@echo OFF


:: Replace c:\temp with the directory where folder1 resides.
cd c:\temp


:: You can make this more generic by passing in args for the source and destination folders.
for /f "usebackq" %%I in (`dir /b /s /a:-d folder1`) do @echo %%~nxI | find /V "data.zip" | find /v "info.txt" >> exclude_list.txt
xcopy folder1 copy_of_folder1 /EXCLUDE:exclude_list.txt /E /I

一次复制一个文件且不需要 ROBOCOPY 的替代解决方案:

@echo off
setlocal enabledelayedexpansion


set "SOURCE_DIR=C:\Source"
set "DEST_DIR=C:\Destination"
set FILENAMES_TO_COPY=data.zip info.txt


for /R "%SOURCE_DIR%" %%F IN (%FILENAMES_TO_COPY%) do (
if exist "%%F" (
set FILE_DIR=%%~dpF
set FILE_INTERMEDIATE_DIR=!FILE_DIR:%SOURCE_DIR%=!
xcopy /E /I /Y "%%F" "%DEST_DIR%!FILE_INTERMEDIATE_DIR!"
)
)

外层 for 语句生成 SOURCE_DIR中的子目录和 FILENAMES_TO_COPY中的 name 的任何可能的路径组合。对于每个现有文件调用 xcopy。FILE_INTERMEDIATE_DIR在需要在 DEST_DIR中创建的 SOURCE_DIR中保存文件的子目录路径。

为了实现这一点,可以通过使用 winzip 来实现拖放操作,这里有一个 dir 结构保留选项。只要创建一个新的。在目录级别的 zip,这将是您的根和拖动文件在。

感谢前面的回答:)

这个名为“ r4k4copy.cmd”的脚本:

@echo off
for %%p in (SOURCE_DIR DEST_DIR FILENAMES_TO_COPY) do set %%p=
cls
echo :: Copy Files Including Folder Tree
echo :: http://stackoverflow.com
rem     /questions/472692/how-to-copy
rem     -a-directory-structure-but-only
rem     -include-certain-files-using-windows
echo :: ReScripted by r4k4
echo.
if "%1"=="" goto :NoParam
if "%2"=="" goto :NoParam
if "%3"=="" goto :NoParam
setlocal enabledelayedexpansion
set SOURCE_DIR=%1
set DEST_DIR=%2
set FILENAMES_TO_COPY=%3
for /R "%SOURCE_DIR%" %%F IN (%FILENAMES_TO_COPY%) do (
if exist "%%F" (
set FILE_DIR=%%~dpF
set FILE_INTERMEDIATE_DIR=!FILE_DIR:%SOURCE_DIR%=!
xcopy /E /I /Y "%%F" "%DEST_DIR%!FILE_INTERMEDIATE_DIR!"
)
)
goto :eof
:NoParam
echo.
echo Syntax: %0 [Source_DIR] [Dest_DIR] [FileName]
echo Eg.   : %0 D:\Root E:\Root\Lev1\Lev2\Lev3 *.JPG
echo Means : Copy *.JPG from D:\Root to E:\Root\Lev1\Lev2\Lev3

它接受变量“ Source”、“ Destination”和“ FileName”。 它还只能复制指定类型的文件或选择性文件名。

任何改进都是受欢迎的。 :)

尝试将 find (即文件路径)的输出通过管道传输到 cpio

find . -type f -name '*.jpg' | cpio -p -d -v targetdir/

Cpio 检查目标文件的时间戳——因此它是安全和快速的。

一旦你习惯了它,移除 -v 来实现更快的操作。

Under Linux and other UNIX systems, using the tar command would do this easily.

$ tar cvf /tmp/full-structure.tar *data.zip *info.txt

然后你靠近目标:

$ tar xvf /tmp/full-structure.tar

当然,您可以将第一个 tar 的输出通过管道传输到第二个 tar,但是看到它按步骤工作更容易理解和解释。我在下面的命令中遗漏了必要的 cd/to/new/path/-我只是不记得现在怎么做了。希望别人能加进去。

$ tar cvf -  *data.zip *info.txt |  tar xvf -

Tar (gnutar)也可以在 Windows 上使用,但是我可能会在那个平台上使用 xcopy方法。

只包含 find 和 cp:

mkdir /tmp/targetdir
cd sourcedir
find . -type f -name '*.zip' -exec cp -p --parents {} /tmp/targetdir ";"
find . -type f -name '*.txt' -exec cp -p --parents {} /tmp/targetdir ";"

对于那些使用 阿尔塔普火蜥蜴(2面板文件管理器) : 在选项的复制弹出式,只需指定文件名称或掩码。放松。

我对正则表达式很满意,懒惰而且不喜欢安装,所以我创建了一个批处理文件,用普通的 DOS 命令创建目录并进行复制。看起来很费力,但对我来说比机器人复制要快。

  1. 在文本文件中创建具有完整路径的源文件列表,包括驱动器号 if nec。
  2. 在文本编辑器中打开正则表达式。
  3. 在每一行中添加双引号-搜索字符串 (.*)替换字符串 "\1",然后单击“全部替换”
  4. 每个文件创建两行-一行创建目录,一行复制文件(qqq 将被替换为目标路径)-搜索字符串 (.*)替换字符串 md qqq\1\nxcopy \1 qqq\1\n并单击替换所有
  5. 从目标路径中删除文件名-搜索 \\([^\\^"]+)"\n取代 \\"\n
  6. 在目标路径中替换(在本例中为 A:\srcB:\dest)。关闭正则表达式,搜索 qqq"A:\src\并替换 B:\dest\,然后单击“替换所有”。

Md 将创建嵌套目录。在本例中,copy 的行为可能与 xcopy 相同。您可能需要将/Y 添加到 xcopy 以禁止覆盖确认。最终得到的批处理文件如下:

md "B:\dest\a\b\c\"
xcopy "C:\src\a\b\c\e.xyz" "B:\dest\a\b\c\e.xyz"

对原始列表中的每个文件重复。在 Win7上测试。

如果 Powershell 是一个选项,您可以这样做:

Copy-Item c:\sourcePath d:\destinationPath -filter data.zip -recurse

主要的缺点是它会复制所有文件夹,即使它们最终都是空的,因为没有文件匹配您指定的筛选器。因此,除了少数拥有所需文件的文件夹之外,您最终可能会得到一个满是空文件夹的树。

使用 WinRAR 命令行界面,您可以将文件名和/或文件类型复制到归档文件中。然后您可以将该存档解压缩到您喜欢的任何位置。这将保留原始文件结构。

我需要添加丢失的相册图片文件到我的手机,而不必复制音乐本身。幸运的是,我的电脑和手机上的目录结构是一样的!

我用:

   rar a -r C:\Downloads\music.rar X:\music\Folder.jpg
  • C: 下载 music.rar = 要创建的存档
  • 包含音乐文件的文件夹
  • Jpg = 我想要复制的文件名

这样就创建了一个存档,其中包含正确子目录中的所有 Folder.jpg 文件。

此技术也可用于复制文件类型。如果所有文件都有不同的名称,您可以选择将所有文件解压缩到单个目录。其他命令行参数可以归档多个文件类型。

More information in this very helpful link http://cects.com/using-the-winrar-command-line-tools-in-windows/

将所有文本文件复制到 G: 并保留目录结构:

xcopy *.txt /s G: