วิธีคัดลอกโครงสร้างไดเร็กทอรี แต่รวมเฉพาะไฟล์บางไฟล์ (โดยใช้ไฟล์แบตช์ Windows)


103

ตามชื่อเรื่องฉันจะคัดลอกโครงสร้างไดเร็กทอรีซ้ำได้อย่างไร แต่รวมเฉพาะบางไฟล์เท่านั้น เช่นกำหนดโครงสร้างไดเร็กทอรีต่อไปนี้:

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

คำตอบ:


169

คุณไม่ได้ระบุว่าต้องเป็นแบทช์เท่านั้น แต่ถ้าคุณสามารถใช้ได้ROBOCOPYให้ลองทำดังนี้:

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

แก้ไข: เปลี่ยน/Sพารามิเตอร์/Eเพื่อรวมโฟลเดอร์ว่าง


ฉันสามารถคัดลอก * .zip ด้วยไวยากรณ์นี้ได้หรือไม่ ฉันลองเขียน * .zip แทน data.zip แต่มันไม่ได้คัดลอกไฟล์มี แต่โฟลเดอร์เท่านั้น ฉันลองด้วยหรือไม่. zip
Niels Brinch

@ นีลส์บรินช์ใช่คุณควรจะทำได้ บรรทัดคำสั่งที่แน่นอนที่คุณใช้คืออะไร?
คำพังเพย

1
ROBOCOPY C: \ Source C: \ Destination * .zip / E
Niels Brinch

แปลก. คุณใช้ระบบปฏิบัติการอะไร คุณมีสิทธิ์ไฟล์ / โฟลเดอร์ที่จำเป็นหรือไม่? ฉันเพิ่งทดสอบกับ Win 7 และ*.zipได้ผลสำหรับฉัน
คำพังเพย

จริงๆ!? ฉันใช้ Win 7 ด้วยเมื่อฉันลองมันก็ไม่ได้คัดลอกไฟล์ใด ๆ โฟลเดอร์เท่านั้น ฉันจะลองอีกครั้ง (ในขณะที่เรากำลังทำมันไวยากรณ์ที่จะรวมมากกว่า * .zip คืออะไร - สมมติว่า * .zip และ * .jpg
Niels Brinch

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!"
    )
)

ด้านนอกงบสร้างรวมกันใด ๆ ที่เป็นไปได้เส้นทางของไดเรกทอรีย่อยในและชื่อในSOURCE_DIR FILENAMES_TO_COPYสำหรับแต่ละไฟล์ที่มีอยู่ xcopy จะถูกเรียกใช้ FILE_INTERMEDIATE_DIRเก็บพา ธ ไดเร็กทอรีย่อยของไฟล์SOURCE_DIRซึ่งจำเป็นต้องสร้างในDEST_DIRไฟล์.


1
ฉันต้องการคัดลอกรูปภาพทั้งหมดจากโฟลเดอร์และโฟลเดอร์ย่อยสคริปต์ชุดนี้ช่วยได้ เพิ่งเปลี่ยนบรรทัดset FILENAMES_TO_COPY=data.zip info.txtด้านบนเป็นset FILENAMES_TO_COPY=*.jpg
Kai Noack

ฉันได้รับข้อผิดพลาดเนื่องจากเส้นทางของไฟล์มีช่องว่างอยู่ (SOURCE_DIR = "C: \ Origin Test", DEST_DIR = "C: \ Dest Test" ข้อผิดพลาด: Test "" ไม่คาดคิดในขณะนี้) ฉันพยายามเปลี่ยน% var% โดย! var! ทุกหนทุกแห่ง แต่ไม่ประสบความสำเร็จ มีเบาะแสเกี่ยวกับวิธีแก้ปัญหานี้หรือไม่? โครงสร้างทั้งหมดเต็มไปด้วยชื่อโฟลเดอร์ที่มีช่องว่าง
ricardo.scholz

1
ลองset "SOURCE_DIR=C:\Origin Test"และset "DEST_DIR=C:\Dest Test". สังเกตตำแหน่งของเครื่องหมายคำพูดคู่
sakra

13

ลองไพพ์เอาต์พุตของ find (เช่นเส้นทางไฟล์) ไปยัง cpio

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

cpio ตรวจสอบการประทับเวลาของไฟล์เป้าหมาย - ดังนั้นจึงปลอดภัยและรวดเร็ว

ลบ -v เพื่อการทำงานที่เร็วขึ้นเมื่อคุณคุ้นเคยกับมัน


2
@ คริสเตียนมีการพึ่งพา cpio ซึ่งไม่ได้เป็นส่วนหนึ่งของการติดตั้งมาตรฐาน
Crashworks

8

หาก Powershell เป็นตัวเลือกคุณสามารถทำได้:

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

ข้อเสียเปรียบหลักคือการคัดลอกโฟลเดอร์ทั้งหมดแม้ว่าโฟลเดอร์เหล่านั้นจะว่างเปล่าเนื่องจากไม่มีไฟล์ที่ตรงกับตัวกรองที่คุณระบุ ดังนั้นคุณสามารถจบลงด้วยต้นไม้ที่เต็มไปด้วยโฟลเดอร์ว่าง ๆ นอกเหนือจากโฟลเดอร์ไม่กี่โฟลเดอร์ที่มีไฟล์ที่คุณต้องการ


การเรียกใช้ครั้งที่สองจะเปลี่ยนจุดหมายปลายทาง (มันทำให้ไฟล์อยู่ในโฟลเดอร์ย่อย) มันเป็นพฤติกรรมโง่ ๆ ถ้าคุณถามฉัน คุณจะต้องเรียกใช้rm -r -ErrorAction:SilentlyContinue d:\destinationPathก่อนที่จะคัดลอกเพื่อแก้ไขปัญหานั้น
MakotoE

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" นอกจากนี้ยังสามารถคัดลอกไฟล์ประเภทที่ระบุหรือชื่อไฟล์ที่เลือกเท่านั้น

ยินดีต้อนรับการปรับปรุงใด ๆ :)


5

ด้วย 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 ";"

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

4

ในการคัดลอกไฟล์ข้อความทั้งหมดไปยัง G: และรักษาโครงสร้างไดเร็กทอรี:

xcopy *.txt /s G:

สามารถทำงานซ้ำได้เช่นการคัดลอก. txt ทั้งหมดจากโฟลเดอร์ย่อยและการรักษาโครงสร้างไดเร็กทอรีที่สัมพันธ์กับไดเร็กทอรีฐานหรือไม่
มิกก้า

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 มีคำสั่งเพียงพอสำหรับสิ่งนี้)


ขอบคุณมาก. ดังที่คุณกล่าวมามันไม่เหมาะอย่างยิ่งเพราะ (ในกรณีของฉัน) ไฟล์ที่ต้องคัดลอกมักมีขนาดเล็กในขณะที่ไฟล์ที่ไม่ควรคัดลอกนั้นมีขนาดใหญ่กว่า (และอาจมีจำนวนมาก)
M4N

2

ภายใต้ Linux และระบบ UNIX อื่น ๆ การใช้tarคำสั่งจะทำได้อย่างง่ายดาย

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

จากนั้นคุณจะ cwd ไปยังเป้าหมายและ:

$ tar xvf /tmp/full-structure.tar 

แน่นอนว่าคุณสามารถต่อเอาท์พุตจากน้ำมันดินตัวแรกไปยังน้ำมันดินตัวที่ 2 ได้ แต่การเห็นว่ามันทำงานเป็นขั้นตอนนั้นง่ายต่อการเข้าใจและอธิบาย ฉันไม่มี cd / to / new / path / ที่จำเป็นในคำสั่งต่อไปนี้ - ฉันจำวิธีการทำไม่ได้ในตอนนี้ มีคนอื่นสามารถเพิ่มได้หวังว่า

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

Tar (gnutar) มีอยู่ใน Windows ด้วย แต่ฉันอาจใช้xcopyวิธีนี้ด้วยตัวเองบนแพลตฟอร์มนั้น


tar cvf /tmp/full-structure.tar ** / data.zip ** / info.txt ทำงานให้ฉัน
ssinganamalla

ทั้ง "tar cvf /tmp/full-structure.tar ** / data.zip ** / info.txt" และ "tar cvf /tmp/full-structure.tar * data.zip * info.txt" ทำให้ฉันมีข้อผิดพลาด 3 รายการ : (1) "tar: * data.zip: ไม่สามารถ stat: ไม่มีไฟล์หรือไดเร็กทอรี", (2) "tar * info.txt: ไม่สามารถ stat: ไม่มีไฟล์หรือไดเร็กทอรีดังกล่าว", (3) "tar: ออกด้วย สถานะความล้มเหลวเนื่องจากข้อผิดพลาดก่อนหน้านี้ " ฉันทำทั้งหมดนี้จากโฟลเดอร์ whcih หรือไม่ ฉันไม่เข้าใจวิธีนี้
user1271772

คำถามระบุว่า WINDOWS
Anfelipe

Win10 มี WSL ซึ่งทำให้ถูกต้อง tar มีให้บริการบน Windows มานานกว่า 20 ปีแล้วและการใช้ไปป์ก็ใช้ได้ผลมาตั้งแต่สมัย MS-DOS ในทุกสภาพแวดล้อมของเชลล์ PWD มีความสำคัญ PWD - นำเสนอไดเร็กทอรีการทำงาน ฉันจะยอมรับว่าโซลูชันนี้น้อยลงสำหรับผู้ใช้ปลายทางและอื่น ๆ สำหรับผู้ใช้ระดับสูงหรือโปรแกรมเมอร์
JohnP

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

แก้ไข:หากคุณต้องการรักษาโฟลเดอร์ว่าง (ซึ่งในการอ่านโพสต์ของคุณซ้ำดูเหมือนว่าคุณจะ) ใช้ / E แทน / S


1
มันไม่ได้รักษาโครงสร้างโฟลเดอร์
Paulius

ตัวเลือก / E จะรักษาโครงสร้างโฟลเดอร์รวมถึงการสร้างโฟลเดอร์ว่างหากจำเป็น ชื่อไฟล์ยังใช้งานได้กับสัญลักษณ์แทน (เช่น folder1 \ *. zip) ฉันได้รับ "ข้อผิดพลาดไม่พบไฟล์" เมื่อฉันส่งชื่อไฟล์แบบเต็มที่ไม่มีอยู่จริง (ในกรณีนี้ฉันได้รับ "File not found - xxx.xxx 0 File (s) copied" เมื่อฉันให้รูปแบบ ที่ไม่ส่งคืนไฟล์ใด ๆ (เช่น folder1 \ *. zzz) ฉันเพิ่งได้รับ "0 File (* s) copy"
gkrogers

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/



0

ฉันสบายดีกับนิพจน์ทั่วไปขี้เกียจและไม่ชอบติดตั้งดังนั้นฉันจึงสร้างไฟล์แบตช์ที่สร้างไดเร็กทอรีและคัดลอกด้วยคำสั่ง vanilla DOS ดูเหมือนจะลำบาก แต่เร็วกว่าสำหรับฉันมากกว่าการใช้ robocopy

  1. สร้างรายการไฟล์ต้นฉบับของคุณด้วยพา ธ ที่สมบูรณ์รวมถึงอักษรระบุไดรฟ์หาก nec ในไฟล์ข้อความ
  2. เปิดใช้นิพจน์ทั่วไปในโปรแกรมแก้ไขข้อความของคุณ
  3. เพิ่มเครื่องหมายคำพูดคู่รอบแต่ละบรรทัดในกรณีของการเว้นวรรค - สตริงการค้นหา(.*)แทนที่สตริง"\1"และคลิกแทนที่ทั้งหมด
  4. สร้างสองบรรทัดต่อไฟล์ - หนึ่งเพื่อสร้างไดเร็กทอรีหนึ่งเพื่อคัดลอกไฟล์ (qqq จะถูกแทนที่ด้วยพา ธ ปลายทาง) - สตริงการค้นหา(.*)แทนที่สตริงmd qqq\1\nxcopy \1 qqq\1\nและคลิกแทนที่ทั้งหมด
  5. ลบชื่อไฟล์ออกจากพา ธ ปลายทาง - ค้นหา\\([^\\^"]+)"\nแทนที่\\"\n
  6. แทนที่ในเส้นทางปลายทาง (ในตัวอย่างนี้A:\srcและB:\dest) ปิดนิพจน์ทั่วไปค้นหาqqq"A:\src\แทนที่B:\dest\และคลิกแทนที่ทั้งหมด

md จะสร้างไดเรกทอรีที่ซ้อนกัน สำเนาอาจทำงานเหมือนกับ 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


-1

ในการดำเนินการนี้ด้วยการลากและวางให้ใช้ winzip มีตัวเลือกการรักษาโครงสร้าง dir เพียงสร้าง. zip ใหม่ที่ระดับไดเร็กทอรีซึ่งจะเป็นรูทของคุณและลากไฟล์เข้ามา


ขอบคุณ แต่ฉันกำลังมองหาวิธีที่จะใช้กับไฟล์สคริปต์ (แบทช์) ไม่ต้องลากแล้ววาง ...
M4N
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.