디렉터리 구조를 복사하지만 특정 파일 만 포함하는 방법 (Windows 배치 파일 사용)
제목에서 알 수 있듯이 디렉토리 구조를 재귀 적으로 복사하지만 일부 파일 만 포함하려면 어떻게해야합니까? 예를 들어 다음과 같은 디렉토리 구조가 있습니다.
folder1
folder2
folder3
data.zip
info.txt
abc.xyz
folder4
folder5
data.zip
somefile.exe
someotherfile.dll
data.zip 및 info.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.
- Create your list of source files with complete paths, including drive letter if nec, in a text file.
- Switch on regular expressions in your text editor.
- Add double quotes round each line in case of spaces - search string
(.*)
replace string"\1"
, and click replace all - 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 stringmd qqq\1\nxcopy \1 qqq\1\n
and click replace all - Remove the filename from the destination paths – search
\\([^\\^"]+)"\n
replace\\"\n
- Replace in the destination path (in this example
A:\src
andB:\dest
). Turn OFF regular expressions, searchqqq"A:\src\
replaceB:\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:
'Programing' 카테고리의 다른 글
Composer PHP 요구 사항 건너 뛰기 (0) | 2020.09.02 |
---|---|
rails는 yield : area가 content_for에 정의되어 있는지 확인합니다. (0) | 2020.09.02 |
Swift의 Codable을 사용하여 사전으로 인코딩하려면 어떻게해야합니까? (0) | 2020.09.02 |
리플렉션을 사용하여 C #에서 기본 생성자없이 유형의 인스턴스 만들기 (0) | 2020.09.02 |
테이블 수준 백업 (0) | 2020.09.02 |