Bir dizin yapısı nasıl kopyalanır ancak yalnızca belirli dosyaları içerir (Windows toplu iş dosyalarını kullanarak)


103

Başlığın da dediği gibi, bir dizin yapısını yinelemeli olarak nasıl kopyalayabilirim, ancak yalnızca bazı dosyaları dahil edebilirim. Örneğin, aşağıdaki dizin yapısı verildiğinde:

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

Data.zip ve info.txt dosyaları , dizin yapısının her yerinde görünebilir. Tam dizin yapısını nasıl kopyalayabilirim, ancak yalnızca data.zip ve info.txt adlı dosyaları dahil edebilirim (diğer tüm dosyalar göz ardı edilmelidir)?

Ortaya çıkan dizin yapısı şu şekilde görünmelidir:

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

Yanıtlar:


169

Yalnızca parti olması gerekip gerekmediğini söylemiyorsunuz, ancak kullanabiliyorsanız şunu ROBOCOPYdeneyin:

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

EDIT: /SParametre /E, boş klasörler içerecek şekilde değiştirildi.


* .Zip dosyasını bu söz dizimiyle kopyalayabilir miyim? Data.zip yerine sadece * .zip yazmayı denedim, ancak bu dosyaları kopyalamadı, yalnızca klasörleri kopyaladı. ?
.Zip

@Niels Brinch Evet, bunu yapabilmelisin. Tam olarak kullandığınız komut satırı nedir?
aphoria

1
ROBOKOPİ C: \ Kaynak C: \ Hedef * .zip / E
Niels Brinch

Tuhaf. Hangi işletim sistemini kullanıyorsunuz? Gerekli dosya / klasör izinlerine sahip misiniz? Win 7'de test ettim ve *.zipbenim için çalıştım.
aphoria

Gerçekten mi!? Ben de Win 7 kullanıyorum. Denediğimde herhangi bir dosya kopyalamıyor. Yalnızca klasörler. Yeniden deneyeceğim. (hazır varken, *
.zip'ten

29

Her seferinde bir dosya kopyalayan ve ROBOKOPİ gerektirmeyen alternatif bir çözüm:

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

Dıştaki for deyimi, içindeki alt dizin SOURCE_DIRve içindeki adın olası yol kombinasyonlarını oluşturur FILENAMES_TO_COPY. Var olan her dosya için xcopy çağrılır. FILE_INTERMEDIATE_DIRiçinde SOURCE_DIRoluşturulması gereken dosyanın alt dizin yolunu tutar DEST_DIR.


1
Tüm fotoğrafları klasörlerden ve alt klasörlerden kopyalamam gerekiyordu, bu toplu komut dosyası yardımcı oldu. set FILENAMES_TO_COPY=data.zip info.txtset FILENAMES_TO_COPY=*.jpg
Kai Noack

Dosya yolunda boşluklar olduğu için bir hata alıyorum (SOURCE_DIR = "C: \ Origin Test", DEST_DIR = "C: \ Dest Test", hata: Test "" şu anda beklenmiyordu). % Var% 'ı! Var! İle değiştirmeye çalıştım! her yerde, ancak başarı olmadan. Bunun nasıl çözüleceğine dair bir ipucu var mı? Tüm yapı, boşluklu klasör adlarıyla doludur.
ricardo.scholz

1
Deneyin set "SOURCE_DIR=C:\Origin Test"ve set "DEST_DIR=C:\Dest Test". Çift tırnakların yerleşimine dikkat edin.
sakra

13

find'ın borulama çıktısını (yani dosya yolunu) cpio'ya deneyin

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

cpio, hedef dosyalardaki zaman damgasını kontrol eder - böylece güvenli ve hızlıdır.

Bir kez alıştıktan sonra daha hızlı işlem için -v'yi kaldırın.


2
@Christian, standart kurulumun parçası olmayan cpio'ya bağımlıdır.
Crashworks

8

Powershell bir seçenekse, bunu yapabilirsiniz:

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

En büyük dezavantajı, belirttiğiniz filtreyle eşleşen hiçbir dosya olmadığı için boş kalsa bile tüm klasörleri kopyalamasıdır. Böylece, istediğiniz dosyaların bulunduğu birkaç klasöre ek olarak, boş klasörlerle dolu bir ağaç elde edebilirsiniz.


Bunu ikinci kez çalıştırmak hedefi değiştirecektir. (Dosyaları bir alt klasöre koyar.) Bana sorarsan bu aptalca bir davranış. Bunu rm -r -ErrorAction:SilentlyContinue d:\destinationPathdüzeltmek için kopyalamadan önce çalıştırmak isteyeceksiniz .
MakotoE

7

Önceki Cevaplara Teşekkür Ederiz. :)

"R4k4copy.cmd" adlı bu komut dosyası:

@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

"Kaynak", "Hedef" ve "DosyaAdı" değişkenlerini kabul eder. Ayrıca, yalnızca belirtilen dosya türlerini veya seçili dosya adlarını kopyalayabilir.

Herhangi bir gelişme açığız. :)


5

Yalnızca bul ve cp ile:

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'un çözümüne benzer, ancak umursamadığınız dosyalar kopyalanmaz ve silinmez:

@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

Tüm metin dosyalarını G'ye kopyalamak ve dizin yapısını korumak için:

xcopy *.txt /s G:

bu, alt klasörlerden tüm .txt dosyasını kopyalamak ve temel dizine göre dizin yapısını korumak gibi yinelemeli olarak çalışabilir mi?
Micka

3

Bu yalnızca iki basit komut, ancak kopyalamanıza gerek YOK olan dosyalar küçük olmadığı sürece bunu önermem. Bunun nedeni, TÜM dosyaları kopyalayacak ve ardından kopyada gerekli olmayan dosyaları kaldıracaktır.

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"

Tabii, ikinci komut biraz uzun ama işe yarıyor!

Ayrıca, bu yaklaşım herhangi bir üçüncü taraf aracı indirmenizi ve yüklemenizi gerektirmez (Windows 2000+ BATCH bunun için yeterli komuta sahiptir).


Çok teşekkürler. Bahsettiğiniz gibi, ideal değil, çünkü (benim durumumda) kopyalanması gereken dosyalar genellikle küçükken kopyalanmaması gereken dosyalar daha büyüktür (ve çok sayıda olabilir).
M4N

2

Linux ve diğer UNIX sistemlerinde, tarkomutu kullanmak bunu kolayca yapacaktır.

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

Sonra hedefe ulaşırsın ve:

$ tar xvf /tmp/full-structure.tar 

Elbette çıktıyı ilk katranın 2.'sine aktarabilirsiniz, ancak adım adım çalıştığını görmek, anlamak ve açıklamak daha kolaydır. Aşağıdaki komutta gerekli cd / to / new / path / eksik - şimdi nasıl yapılacağını hatırlamıyorum. Umarım başka biri ekleyebilir.

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

Tar (gnutar) Windows'ta da mevcuttur, ancak muhtemelen xcopybu platformda kendim de bu yöntemi kullanırım .


tar cvf /tmp/full-structure.tar ** / data.zip ** / info.txt benim için çalıştı
ssinganamalla

Hem "tar cvf /tmp/full-structure.tar ** / data.zip ** / info.txt" hem de "tar cvf /tmp/full-structure.tar * data.zip * info.txt" bana 3 hata verdi : (1) "tar: * data.zip: Statü yapılamaz: Böyle bir dosya veya dizin yok", (2) "tar * info.txt: Statü yapılamaz: Böyle bir dosya veya dizin yok", (3) "tar: ile çıkılıyor önceki hatalardan kaynaklanan arıza durumu ". Tüm bunları hangi klasörden yapıyorum? Bu yöntemi anlamıyorum.
user1271772

Soru WINDOWS
Anfelipe

Win10, bunu geçerli kılan WSL'ye sahiptir. tar, Windows'ta 20+ yıldan beri mevcuttur ve MS-DOS günlerinden beri bir kanal kullanımı işe yaramıştır. Herhangi bir kabuk ortamında PWD önemlidir. PWD - mevcut çalışma dizini. Bu çözümün son kullanıcılar için daha az ve uzman kullanıcılar veya programcılar için daha fazla olduğunu kabul edeceğim.
JohnP

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

DÜZENLEME: Boş klasörleri korumak istiyorsanız (ki, yayınınızı yeniden okurken, görünüşe göre) / S yerine / E kullanın.


1
klasör yapısını korumaz.
Paulius

/ E seçeneği, gerekirse boş klasörler oluşturmak da dahil olmak üzere klasör yapısını korur. Dosya adı ayrıca bir joker karakterle de çalışır (örn. Klasör1 \ *. Zip). Var olmayan bir tam dosya adını ilettiğimde sadece "Dosya bulunamadı" hatasını alıyorum (bu durumda "Dosya bulunamadı - xxx.xxx 0 Dosya kopyalandı" mesajı alıyorum. Ona bir kalıp verdiğimde hiç dosya döndürmeyen (ör. klasör1 \ *. zzz), sadece "0 Dosya kopyalandı"
alıyorum

1

WinRAR komut satırı arayüzünü kullanarak, dosya adlarını ve / veya dosya türlerini bir arşive kopyalayabilirsiniz. Ardından bu arşivi istediğiniz konuma çıkarabilirsiniz. Bu, orijinal dosya yapısını korur.

Müziğin kendisini yeniden kopyalamak zorunda kalmadan eksik albüm resim dosyalarını cep telefonuma eklemem gerekiyordu. Neyse ki bilgisayarımda ve cep telefonumda dizin yapısı aynıydı!

Kullandım:

   rar a -r C:\Downloads\music.rar X:\music\Folder.jpg
  • C: \ İndirilenler \ music.rar = Oluşturulacak arşiv
  • X: \ music \ = Müzik dosyalarını içeren klasör
  • Folder.jpg = Kopyalamak istediğim dosya adı

Bu, uygun alt dizinlerdeki tüm Folder.jpg dosyalarını içeren bir arşiv oluşturdu.

Bu teknik, dosya türlerini kopyalamak için de kullanılabilir. Dosyaların tümünün farklı adları varsa, tüm dosyaları tek bir dizine çıkarmayı seçebilirsiniz. Ek komut satırı parametreleri birden çok dosya türünü arşivleyebilir.

Bu çok yararlı bağlantıda daha fazla bilgi http://cects.com/using-the-winrar-command-line-tools-in-windows/


1

Altap Salamander (2 panel dosya yöneticisi) kullananlar için : Kopyala açılır penceresinin Seçeneklerinde, dosya adlarını veya maskeleri belirtmeniz yeterlidir. Kolay.


0

Normal ifadeler konusunda iyiyim, tembel ve yüklemelere karşı isteksizim, bu yüzden dizini oluşturan ve vanilya DOS komutlarıyla kopyalayan bir toplu iş dosyası oluşturdum. Zahmetli görünüyor ama benim için robokopi yapmaktan daha hızlı.

  1. Bir metin dosyasında, gerekirse sürücü harfi de dahil olmak üzere tam yollarla kaynak dosyalar listenizi oluşturun.
  2. Metin düzenleyicinizde normal ifadeleri açın.
  3. Boşluk olması durumunda her satıra çift tırnak işareti ekleyin - arama dizesi dizeyi (.*)değiştirin "\1"ve tümünü değiştir'e tıklayın
  4. Dosya başına iki satır oluşturun - biri dizini oluşturmak için, diğeri dosyayı kopyalamak için (qqq, hedef yolla değiştirilecektir) - dizeyi arama dizesini (.*)değiştirin md qqq\1\nxcopy \1 qqq\1\nve tümünü değiştir'e tıklayın
  5. Dosya adını hedef yollardan kaldırın - \\([^\\^"]+)"\ndeğiştirme ara\\"\n
  6. Hedef yolda değiştirin (bu örnekte A:\srcve B:\dest). Normal ifadeleri KAPATIN, qqq"A:\src\değiştirmeyi arayın B:\dest\ve tümünü değiştir'i tıklayın.

md, iç içe dizinler oluşturur. copy, muhtemelen bu örnekteki xcopy ile aynı şekilde davranacaktır. Üzerine yazma onaylarını engellemek için xcopy'ye / Y eklemek isteyebilirsiniz. Bunun gibi bir toplu iş dosyası elde edersiniz:

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

orijinal listenizdeki her dosya için tekrarlanır. Win7'de test edildi.


-1

Bunu sürükle ve bırak ile yapmak için winzip kullanın, bir dir yapı koruma seçeneği vardır. Basitçe, dizin düzeyinde, kökünüz olacak yeni bir .zip oluşturun ve dosyaları içine sürükleyin.


Teşekkürler, ama komut dosyası (toplu iş) dosyalarından kullanılacak bir çözüm arıyordum. Yani sürükle ve bırak yok ...
M4N
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.