Programing

디렉터리 구조를 복사하지만 특정 파일 만 포함하는 방법 (Windows 배치 파일 사용)

lottogame 2020. 9. 2. 20:25
반응형

디렉터리 구조를 복사하지만 특정 파일 만 포함하는 방법 (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라는 파일 만 포함하려면 어떻게해야합니까 (다른 모든 파일은 무시해야 함)?

결과 디렉토리 구조는 다음과 같습니다.

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

배치 전용이어야하는지 언급하지 않지만을 사용할 수 있으면 다음을 ROBOCOPY시도하십시오.

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

편집 : 빈 폴더를 포함 하도록 /S매개 변수를 변경했습니다 /E.


한 번에 하나의 파일을 복사하고 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. 기존 파일 각각에 대해 xcopy가 호출됩니다. 에서 만들어야 FILE_INTERMEDIATE_DIR하는 파일의 하위 디렉터리 경로를 SOURCE_DIR포함합니다 DEST_DIR.


find 출력 (즉, 파일 경로)을 cpio로 파이핑 해보십시오.

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

cpio는 대상 파일의 타임 스탬프를 확인하므로 안전하고 빠릅니다.

일단 익숙해지면 더 빠른 작업을 위해 -v를 제거하십시오.


Powershell이 ​​옵션 인 경우 다음을 수행 할 수 있습니다.

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

가장 큰 단점은 지정한 필터와 일치하는 파일이 없기 때문에 비어있는 경우에도 모든 폴더를 복사한다는 것입니다. 따라서 원하는 파일이있는 몇 개의 폴더 외에도 빈 폴더로 가득 찬 트리를 만들 수 있습니다.


이전 답변에 감사드립니다. :)

"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

It accepts variable of "Source", "Destination", and "FileName". It also can only copying specified type of files or selective filenames.

Any improvement are welcome. :)


With find and cp only:

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 ";"

Similar to Paulius' solution, but the files you don't care about are not copied then deleted:

@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

That's only two simple commands, but I wouldn't recommend this, unless the files that you DON'T need to copy are small. That's because this will copy ALL files and then remove the files that are not needed in the copy.

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!

Also, this approach doesn't require you to download and install any third party tools (Windows 2000+ BATCH has enough commands for this).


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

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

Then you'd cwd to the target and:

$ tar xvf /tmp/full-structure.tar 

Of course you could pipe the output from the first tar into the 2nd, but seeing it work in steps is easier to understand and explain. I'm missing the necessary cd /to/new/path/ in the following command - I just don't recall how to do it now. Someone else can add it, hopefully.

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

Tar (gnutar) is available on Windows too, but I'd probably use the xcopy method myself on that platform.


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

EDIT: If you want to preserve the empty folders (which, on rereading your post, you seem to) use /E instead of /S.


Using WinRAR command line interface, you can copy the file names and/or file types to an archive. Then you can extract that archive to whatever location you like. This preserves the original file structure.

I needed to add missing album picture files to my mobile phone without having to recopy the music itself. Fortunately the directory structure was the same on my computer and mobile!

I used:

   rar a -r C:\Downloads\music.rar X:\music\Folder.jpg
  • C:\Downloads\music.rar = Archive to be created
  • X:\music\ = Folder containing music files
  • Folder.jpg = Filename I wanted to copy

This created an archive with all the Folder.jpg files in the proper subdirectories.

This technique can be used to copy file types as well. If the files all had different names, you could choose to extract all files to a single directory. Additional command line parameters can archive multiple file types.

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


For those using Altap Salamander (2 panels file manager) : in the Options of the Copy popup, just specify the file names or masks. Easy.


I am fine with regular expressions, lazy and averse to installs, so I created a batch file that creates the directory and copies with vanilla DOS commands. Seems laborious but quicker for me than working out robocopy.

  1. Create your list of source files with complete paths, including drive letter if nec, in a text file.
  2. Switch on regular expressions in your text editor.
  3. Add double quotes round each line in case of spaces - search string (.*) replace string "\1", and click replace all
  4. Create two lines per file - one to create the directory, one to copy the file (qqq will be replaced with destination path) - search string (.*) replace string md qqq\1\nxcopy \1 qqq\1\n and click replace all
  5. Remove the filename from the destination paths – search \\([^\\^"]+)"\n replace \\"\n
  6. Replace in the destination path (in this example A:\src and B:\dest). Turn OFF regular expressions, search qqq"A:\src\ replace B:\dest\ and click replace all.

md will create nested directories. copy would probably behave identically to xcopy in this example. You might want to add /Y to xcopy to suppress overwrite confirms. You end up with a batch file like so:

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

repeated for every file in your original list. Tested on Win7.


To do this with drag and drop use winzip there's a dir structure preserve option. Simply create a new .zip at the directory level which will be your root and drag files in.


To copy all text files to G: and preserve directory structure:

xcopy *.txt /s G:

참고URL : https://stackoverflow.com/questions/472692/how-to-copy-a-directory-structure-but-only-include-certain-files-using-windows

반응형