116

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

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

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

生成的目录结构应如下所示:

copy_of_folder1
  folder2
    folder3
      data.zip
      info.txt
    folder4
    folder5
      data.zip
4

15 回答 15

185

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

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

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

于 2009-01-23T12:25:12.560 回答
29

一次复制一个文件且不需要 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 语句生成子目录 inSOURCE_DIR和 name in的任何可能的路径组合FILENAMES_TO_COPY。对于每个现有文件,都会调用 xcopy。保存需要FILE_INTERMEDIATE_DIR在其中创建的文件的子目录路径。SOURCE_DIRDEST_DIR

于 2009-07-09T14:48:23.083 回答
16

尝试将 find 的输出(即文件路径)传递到 cpio

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

cpio 检查目标文件上的时间戳——因此它既安全又快速。

一旦你习惯了它,删除 -v 以获得更快的操作。

于 2012-12-18T20:40:52.267 回答
11

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

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

主要缺点是它会复制所有文件夹,即使它们最终会是空的,因为没有文件与您指定的过滤器匹配。因此,除了包含所需文件的少数文件夹外,您最终可能会得到一棵充满空文件夹的树。

于 2015-03-16T17:12:50.550 回答
10

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

xcopy *.txt /s G:
于 2018-02-28T21:18:55.570 回答
7

感谢以前的答案。:)

此脚本名为“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”的变量。它也只能复制指定类型的文件或选择性文件名。

欢迎任何改进。:)

于 2011-11-10T04:26:50.137 回答
6

仅使用 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 ";"
于 2014-01-09T15:34:49.247 回答
4

类似于 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
于 2009-01-23T14:10:38.183 回答
3

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

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"

当然,第二个命令有点长,但它有效!

此外,这种方法不需要您下载和安装任何第三方工具(Windows 2000+ BATCH 对此有足够的命令)。

于 2009-01-23T13:33:55.497 回答
2

在 Linux 和其他 UNIX 系统下,使用该tar命令可以轻松完成此操作。

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

然后你会 cwd 到目标,然后:

$ tar xvf /tmp/full-structure.tar 

当然,您可以将第一个 tar 的输出通过管道传输到第二个,但是看到它逐步工作更容易理解和解释。我在以下命令中缺少必要的 cd /to/new/path/ - 我只是不记得现在该怎么做。其他人可以添加它,希望。

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

Tar (gnutar) 也可在 Windows 上使用,但我可能会xcopy在该平台上自己使用该方法。

于 2013-04-18T14:56:00.317 回答
1
XCOPY /S folder1\data.zip copy_of_folder1  
XCOPY /S folder1\info.txt copy_of_folder1

编辑:如果您想保留空文件夹(在重读您的帖子时,您似乎会这样做)使用 /E 而不是 /S。

于 2009-01-23T12:32:03.250 回答
1

对于那些使用Altap Salamander(2 个面板文件管理器)的用户:在复制弹出窗口的选项中,只需指定文件名或掩码。简单的。

于 2014-02-14T13:57:56.380 回答
1

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

我需要将丢失的专辑图片文件添加到我的手机中,而无需重新复制音乐本身。幸运的是,我的电脑和手机上的目录结构是一样的!

我用了:

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

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

此技术也可用于复制文件类型。如果文件都有不同的名称,您可以选择将所有文件提取到一个目录中。附加的命令行参数可以归档多种文件类型。

此非常有用的链接http://cects.com/using-the-winrar-command-line-tools-in-windows/中的更多信息

于 2016-01-20T16:41:06.450 回答
0

我对正则表达式很好,懒惰且不喜欢安装,所以我创建了一个批处理文件,该文件创建目录并使用 vanilla DOS 命令进行复制。对我来说似乎比使用 robocopy 更费力但更快。

  1. 在文本文件中创建具有完整路径的源文件列表,包括驱动器号(如果 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上测试。

于 2015-02-22T22:58:42.867 回答
-1

要做到这一点拖放使用 winzip 有一个 dir 结构保留选项。只需在目录级别创建一个新的 .zip,这将是您的根目录并将文件拖入。

于 2011-09-10T11:10:41.040 回答