Jak skopiować strukturę katalogów, ale dołączać tylko określone pliki (używając plików wsadowych systemu Windows)

103

Jak mówi tytuł, jak mogę rekurencyjnie skopiować strukturę katalogów, ale dołączać tylko niektóre pliki. Np. Biorąc pod uwagę następującą strukturę katalogów:

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

Pliki data.zip i info.txt może pojawić się wszędzie w strukturze katalogów. Jak mogę skopiować pełną strukturę katalogów, ale dołączać tylko pliki o nazwach data.zip i info.txt (wszystkie inne pliki należy zignorować)?

Wynikowa struktura katalogów powinna wyglądać następująco:

copy_of_folder1
  folder2
    folder3
      data.zip
      info.txt
    folder4
    folder5
      data.zip
M4N
źródło

Odpowiedzi:

169

Nie wspominasz, czy ma to być tylko partia, ale jeśli możesz użyć ROBOCOPY, spróbuj tego:

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

EDYCJA: zmieniono /Sparametr /Ena uwzględnienie pustych folderów.

aforia
źródło
Czy mogę skopiować * .zip z taką składnią? Próbowałem po prostu napisać * .zip zamiast data.zip, ale nie skopiowałem plików, tylko foldery. Próbowałem też?
.Zip
@Niels Brinch Tak, powinieneś być w stanie to zrobić. Jaka jest dokładna linia poleceń, której używasz?
aforia
1
ROBOCOPY C: \ Source C: \ Destination * .zip / E
Niels Brinch
Dziwne. Z jakiego systemu operacyjnego korzystasz? Czy masz niezbędne uprawnienia do plików / folderów? Właśnie przetestowałem Win 7 i *.zippracowałem dla mnie.
aforia,
Naprawdę!? Używam również Win 7. Kiedy próbuję, po prostu nie kopiuje żadnych plików. Tylko foldery. Spróbuję ponownie. (skoro już o tym
mowa
29

Alternatywne rozwiązanie, które kopiuje jeden plik na raz i nie wymaga 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!"
    )
)

Instrukcja external for generuje każdą możliwą kombinację ścieżki podkatalogu SOURCE_DIRi nazwy w FILENAMES_TO_COPY. Dla każdego istniejącego pliku wywoływana jest xcopy. FILE_INTERMEDIATE_DIRprzechowuje ścieżkę do podkatalogu pliku, w SOURCE_DIRktórym ma zostać utworzony w DEST_DIR.

sakra
źródło
1
Musiałem skopiować wszystkie zdjęcia z folderów i podfolderów, ten skrypt wsadowy pomógł. Właśnie zmieniłem set FILENAMES_TO_COPY=data.zip info.txtpowyższą linię naset FILENAMES_TO_COPY=*.jpg
Kai Noack
Otrzymuję błąd, ponieważ ścieżka pliku zawiera spacje (SOURCE_DIR = "C: \ Origin Test", DEST_DIR = "C: \ Dest Test", błąd: "" był nieoczekiwany w tym momencie). Próbowałem zmienić% var% przez! Var! wszędzie, ale bez powodzenia. Jakieś wskazówki, jak to rozwiązać? Cała struktura jest pełna nazw folderów ze spacjami.
ricardo.scholz
1
Spróbuj set "SOURCE_DIR=C:\Origin Test"i set "DEST_DIR=C:\Dest Test". Zwróć uwagę na umieszczenie podwójnych cudzysłowów.
sakra
13

spróbuj przesłać wyjście find (tj. ścieżkę do pliku) do cpio

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

cpio sprawdza sygnaturę czasową na plikach docelowych - więc jest bezpieczny i szybki.

usuń -v dla szybszego działania, gdy już się do tego przyzwyczaisz.

Gabe Rainbow
źródło
2
@Christian ma zależność od cpio, która nie jest częścią standardowej instalacji.
Crashworks
8

Jeśli opcja Powershell jest dostępna, możesz to zrobić:

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

Główną wadą jest to, że kopiuje wszystkie foldery, nawet jeśli zostaną one puste, ponieważ żadne pliki nie pasują do określonego filtru. Więc możesz skończyć z drzewem pełnym pustych folderów, oprócz kilku folderów, które zawierają żądane pliki.

Neil
źródło
Uruchomienie tego po raz drugi zmieni miejsce docelowe. (Pliki są umieszczane w podfolderze). Jeśli o mnie chodzi, to głupie zachowanie. Będziesz chciał uruchomić rm -r -ErrorAction:SilentlyContinue d:\destinationPathprzed skopiowaniem, aby to naprawić.
MakotoE
7

Dzięki za poprzednie odpowiedzi. :)

Ten skrypt o nazwie „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

Akceptuje zmienne „Source”, „Destination” i „FileName”. Może również kopiować tylko określone typy plików lub wybrane nazwy plików.

Wszelkie ulepszenia są mile widziane. :)

Rhak Kahr
źródło
5

Tylko w przypadku funkcji find i 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 ";"
Rop
źródło
4

Podobnie jak w rozwiązaniu Pauliusa, ale pliki, które Cię nie interesują, nie są kopiowane, a następnie usuwane:

@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
Patrick Cuff
źródło
4

Aby skopiować wszystkie pliki tekstowe do G: i zachować strukturę katalogów:

xcopy *.txt /s G:
Osbert Snudge
źródło
czy to może działać rekurencyjnie, jak kopiowanie całego pliku .txt z podfolderów i zachowanie struktury katalogów względem katalogu podstawowego?
Micka
3

To tylko dwa proste polecenia, ale nie polecałbym tego, chyba że pliki, których NIE musisz kopiować, są małe. Dzieje się tak, ponieważ spowoduje to skopiowanie WSZYSTKICH plików, a następnie usunięcie plików, które nie są potrzebne w kopii.

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"

Jasne, drugie polecenie jest trochę długie, ale działa!

Ponadto takie podejście nie wymaga pobierania i instalowania żadnych narzędzi innych firm (system Windows 2000+ BATCH ma do tego wystarczającą liczbę poleceń).

Paulius
źródło
Wielkie dzięki. Jak wspomniałeś, nie jest to idealne rozwiązanie, ponieważ (w moim przypadku) pliki do skopiowania są zwykle małe, natomiast pliki, które nie powinny być kopiowane, są większe (a może być ich dużo).
M4N
2

W Linuksie i innych systemach UNIX użycie tarpolecenia ułatwiłoby to.

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

Następnie podążałeś do celu i:

$ tar xvf /tmp/full-structure.tar 

Oczywiście możesz potokować wyjście z pierwszej tar do drugiej, ale zobaczenie, jak działa w krokach, jest łatwiejsze do zrozumienia i wyjaśnienia. Brakuje mi niezbędnego cd / to / new / path / w następującym poleceniu - po prostu nie pamiętam, jak to zrobić teraz. Miejmy nadzieję, że ktoś inny może to dodać.

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

Tar (gnutar) jest również dostępny w systemie Windows, ale prawdopodobnie xcopysam użyłbym tej metody na tej platformie.

John P.
źródło
tar cvf /tmp/full-structure.tar ** / data.zip ** / info.txt pracował dla mnie
ssinganamalla
Zarówno „tar cvf /tmp/full-structure.tar ** / data.zip ** / info.txt”, jak i „tar cvf /tmp/full-structure.tar * data.zip * info.txt” dały mi 3 błędy : (1) "tar: * data.zip: Cannot stat: Brak takiego pliku lub katalogu", (2) "tar * info.txt: Cannot stat: Brak takiego pliku lub katalogu", (3) "tar: Wyjście z stan awarii z powodu poprzednich błędów ”. Z jakiego folderu mam to wszystko zrobić? Nie rozumiem tej metody.
user1271772
Pytanie brzmi: WINDOWS
Anfelipe
Win10 ma WSL, co czyni to poprawnym. tar był dostępny w systemie Windows od ponad 20 lat, a użycie potoku działało od czasów MS-DOS. W każdym środowisku powłoki PWD jest ważne. PWD - obecny katalog roboczy. Przyznam, że to rozwiązanie jest mniej dla użytkowników końcowych, a więcej dla zaawansowanych użytkowników czy programistów.
JohnP
1
XCOPY /S folder1\data.zip copy_of_folder1  
XCOPY /S folder1\info.txt copy_of_folder1

EDYTUJ: Jeśli chcesz zachować puste foldery (które po ponownym przeczytaniu postu wydają się) użyć / E zamiast / S.

gkrogers
źródło
1
nie zachowuje struktury folderów.
Paulius
Opcja / E zachowuje strukturę folderów, łącznie z tworzeniem pustych folderów, jeśli to konieczne. Nazwa pliku działa również z symbolem wieloznacznym (np. Folder1 \ *. Zip). Otrzymuję tylko komunikat „Błąd nie znaleziono pliku”, gdy przekażę mu pełną nazwę pliku, który nie istnieje (w takim przypadku otrzymuję komunikat „Nie znaleziono pliku - xxx.xxx 0 Plik (i) skopiowane”). Kiedy podam wzór który nie zwraca żadnych plików (np. folder1 \ *. zzz), po prostu otrzymuję „0 Plik (* s) skopiowany”.
gkrogers,
1

Korzystając z interfejsu wiersza poleceń WinRAR, możesz skopiować nazwy plików i / lub typy plików do archiwum. Następnie możesz wyodrębnić to archiwum do dowolnej lokalizacji. Pozwala to zachować oryginalną strukturę plików.

Musiałem dodać brakujące pliki zdjęć albumów do telefonu komórkowego bez konieczności ponownego kopiowania samej muzyki. Na szczęście struktura katalogów na moim komputerze i telefonie komórkowym była taka sama!

Użyłem:

   rar a -r C:\Downloads\music.rar X:\music\Folder.jpg
  • C: \ Downloads \ music.rar = Archiwum do utworzenia
  • X: \ music \ = Folder zawierający pliki muzyczne
  • Folder.jpg = Nazwa pliku, który chciałem skopiować

Spowodowało to utworzenie archiwum ze wszystkimi plikami Folder.jpg w odpowiednich podkatalogach.

Ta technika może być również używana do kopiowania typów plików. Jeśli wszystkie pliki miały różne nazwy, można było wyodrębnić wszystkie pliki do jednego katalogu. Dodatkowe parametry wiersza poleceń mogą archiwizować wiele typów plików.

Więcej informacji w tym bardzo pomocnym linku http://cects.com/using-the-winrar-command-line-tools-in-windows/

Jim_Joat
źródło
1

Dla tych, którzy używają Altap Salamander (menedżer plików z 2 panelami): w opcjach wyskakującego okienka Kopiuj, po prostu określ nazwy plików lub maski. Łatwo.

Hugo P.
źródło
0

Nie mam problemu z wyrażeniami regularnymi, leniwym i niechętnym instalacjom, więc stworzyłem plik wsadowy, który tworzy katalog i kopiuje za pomocą waniliowych poleceń DOS. Wydaje mi się to pracochłonne, ale dla mnie szybsze niż ćwiczenie robocopy.

  1. Utwórz listę plików źródłowych z pełnymi ścieżkami, w tym literą dysku, jeśli nie jest to konieczne, w pliku tekstowym.
  2. Włącz wyrażenia regularne w edytorze tekstu.
  3. Dodaj podwójne cudzysłowy w każdym wierszu w przypadku spacji - szukany ciąg (.*)zamień ciąg "\1"i kliknij zamień wszystko
  4. Utwórz dwie linie na plik - jedną do tworzenia katalogu, drugą do kopiowania pliku (qqq zostanie zastąpione ścieżką docelową) - ciąg wyszukiwania (.*)zastąp ciąg md qqq\1\nxcopy \1 qqq\1\ni kliknij zamień wszystko
  5. Usuń nazwę pliku ze ścieżek docelowych - wyszukaj \\([^\\^"]+)"\nzastąp\\"\n
  6. Zastąp w ścieżce docelowej (w tym przykładzie A:\srci B:\dest). Wyłącz wyrażenia regularne, wyszukaj qqq"A:\src\zastąp B:\dest\i kliknij zamień wszystko.

md utworzy zagnieżdżone katalogi. copy prawdopodobnie zachowałoby się identycznie jak xcopy w tym przykładzie. Możesz chcieć dodać / Y do xcopy, aby pominąć potwierdzenia nadpisania. Otrzymujesz taki plik wsadowy:

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

powtarzane dla każdego pliku z oryginalnej listy. Testowane na Win7.

Chris
źródło
-1

Aby to zrobić za pomocą przeciągania i upuszczania, użyj winzip, istnieje opcja zachowania struktury katalogu. Po prostu utwórz nowy plik .zip na poziomie katalogu, który będzie Twoim głównym katalogiem, i przeciągnij do niego pliki.

Gnoy Dav
źródło
Dzięki, ale szukałem rozwiązania do wykorzystania z plików skryptowych (wsadowych). Tak więc, bez przeciągania i upuszczania ...
M4N