So kopieren Sie eine Verzeichnisstruktur, schließen jedoch nur bestimmte Dateien ein (mithilfe von Windows-Batchdateien)

103

Wie der Titel sagt, wie kann ich eine Verzeichnisstruktur rekursiv kopieren, aber nur einige Dateien einschließen? ZB bei folgender Verzeichnisstruktur:

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

Die Dateien data.zip und info.txt können überall in der Verzeichnisstruktur angezeigt werden. Wie kann ich die vollständige Verzeichnisstruktur kopieren, aber nur Dateien mit den Namen data.zip und info.txt einschließen (alle anderen Dateien sollten ignoriert werden)?

Die resultierende Verzeichnisstruktur sollte folgendermaßen aussehen:

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

Antworten:

169

Sie erwähnen nicht, ob es nur Batch sein muss, aber wenn Sie verwenden können ROBOCOPY, versuchen Sie Folgendes:

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

BEARBEITEN: Der /SParameter wurde so geändert /E, dass er leere Ordner enthält.

Aphorie
quelle
Kann ich * .zip mit dieser Syntax kopieren? Ich habe versucht, nur * .zip anstelle von data.zip zu schreiben, aber es wurden nicht die Dateien kopiert, sondern nur die Ordner. Ich habe auch versucht? .Zip
Niels Brinch
@Niels Brinch Ja, das solltest du können. Was ist die genaue Befehlszeile, die Sie verwenden?
Aphorie
1
ROBOCOPY C: \ Quelle C: \ Ziel * .zip / E
Niels Brinch
Seltsam. Welches Betriebssystem verwenden Sie? Haben Sie die erforderlichen Datei- / Ordnerberechtigungen? Ich habe gerade auf Win 7 getestet und *.zipfür mich gearbeitet.
Aphorie
Ja wirklich!? Ich verwende auch Win 7. Wenn ich es versuche, kopiert es einfach keine Dateien. Nur Ordner. Ich werde es wieder versuchen. (Wenn wir schon dabei sind, wie lautet die Syntax, die mehr als * .zip enthält - sagen wir * .zip und * .jpg.
Niels Brinch
29

Eine alternative Lösung, die jeweils eine Datei kopiert und keine ROBOCOPY erfordert:

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

Die äußere for-Anweisung generiert eine mögliche Pfadkombination aus Unterverzeichnis in SOURCE_DIRund Name in FILENAMES_TO_COPY. Für jede vorhandene Datei wird xcopy aufgerufen. FILE_INTERMEDIATE_DIREnthält den Unterverzeichnispfad der Datei, in SOURCE_DIRdem erstellt werden muss DEST_DIR.

Sakra
quelle
1
Ich musste alle Fotos aus Ordnern und Unterordnern kopieren, dieses Batch-Skript half. Habe gerade die Zeile set FILENAMES_TO_COPY=data.zip info.txtoben geändert inset FILENAMES_TO_COPY=*.jpg
Kai Noack
Ich erhalte eine Fehlermeldung, weil der Dateipfad Leerzeichen enthält (SOURCE_DIR = "C: \ Origin Test", DEST_DIR = "C: \ Dest Test", Fehler: Test "" war in diesem Moment unerwartet). Ich habe versucht,% var% durch! Var! überall, aber ohne Erfolg. Irgendwelche Hinweise, wie man das löst? Die gesamte Struktur ist voll von Ordnernamen mit Leerzeichen.
Ricardo.scholz
1
Versuchen Sie set "SOURCE_DIR=C:\Origin Test"und set "DEST_DIR=C:\Dest Test". Beachten Sie die Platzierung der doppelten Anführungszeichen.
Sakra
13

Versuchen Sie, die Ausgabe von find (dh den Dateipfad) in cpio zu leiten

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

cpio überprüft den Zeitstempel für Zieldateien - so ist es sicher und schnell.

entferne -v für eine schnellere Operation, sobald du dich daran gewöhnt hast.

Gabe Regenbogen
quelle
2
@Christian hat eine Abhängigkeit von cpio, die nicht Teil der Standardinstallation ist.
Crashworks
8

Wenn Powershell eine Option ist, können Sie dies tun:

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

Der Hauptnachteil besteht darin, dass alle Ordner kopiert werden, auch wenn sie leer sind, da keine Dateien mit dem von Ihnen angegebenen Filter übereinstimmen. So könnten Sie zusätzlich zu den wenigen Ordnern, die die gewünschten Dateien enthalten, einen Baum voller leerer Ordner erhalten.

Neil
quelle
Wenn Sie dies ein zweites Mal ausführen, wird das Ziel geändert. (Es legt die Dateien in einem Unterordner ab.) Es ist ein dummes Verhalten, wenn Sie mich fragen. Sie sollten rm -r -ErrorAction:SilentlyContinue d:\destinationPathvor dem Kopieren ausgeführt werden, um dies zu beheben.
MakotoE
7

Dank vorheriger Antworten. :) :)

Dieses Skript mit dem Namen "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

Es akzeptiert die Variablen "Quelle", "Ziel" und "Dateiname". Es kann auch nur bestimmte Dateitypen oder ausgewählte Dateinamen kopieren.

Jede Verbesserung ist willkommen. :) :)

Rhak Kahr
quelle
5

Nur mit find und 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
quelle
4

Ähnlich wie bei Paulius 'Lösung, aber die Dateien, die Sie nicht interessieren, werden nicht kopiert und dann gelöscht:

@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 Manschette
quelle
4

So kopieren Sie alle Textdateien nach G: und behalten die Verzeichnisstruktur bei:

xcopy *.txt /s G:
Osbert Snudge
quelle
Kann dies rekursiv funktionieren, z. B. das Kopieren aller TXT-Dateien aus Unterordnern und das Beibehalten der Verzeichnisstruktur relativ zum Basisverzeichnis?
Micka
3

Das sind nur zwei einfache Befehle, aber ich würde dies nicht empfehlen, es sei denn, die Dateien, die Sie NICHT kopieren müssen, sind klein. Dies liegt daran, dass dadurch ALLE Dateien kopiert und dann die Dateien entfernt werden, die in der Kopie nicht benötigt werden.

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"

Sicher, der zweite Befehl ist ziemlich lang, aber er funktioniert!

Außerdem müssen Sie für diesen Ansatz keine Tools von Drittanbietern herunterladen und installieren (Windows 2000+ BATCH verfügt über genügend Befehle dafür).

Paulius
quelle
Vielen Dank. Wie Sie bereits erwähnt haben, ist dies nicht ideal, da (in meinem Fall) die zu kopierenden Dateien normalerweise klein sind, während die nicht zu kopierenden Dateien größer sind (und möglicherweise viele davon vorhanden sind).
M4N
2

Unter Linux und anderen UNIX-Systemen ist die Verwendung des tarBefehls problemlos möglich.

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

Dann würden Sie zum Ziel cwd und:

$ tar xvf /tmp/full-structure.tar 

Natürlich können Sie die Ausgabe vom ersten Teer in den zweiten leiten, aber es ist einfacher zu verstehen und zu erklären, wie sie schrittweise funktioniert. Ich vermisse die erforderliche CD / to / new / path / im folgenden Befehl - ich kann mich nur nicht erinnern, wie es jetzt geht. Jemand anderes kann es hoffentlich hinzufügen.

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

Tar (gnutar) ist auch unter Windows verfügbar, aber ich würde die xcopyMethode wahrscheinlich selbst auf dieser Plattform verwenden.

JohnP
quelle
tar cvf /tmp/full-structure.tar ** / data.zip ** / info.txt arbeitete für mich
ssinganamalla
Sowohl "tar cvf /tmp/full-structure.tar ** / data.zip ** / info.txt" als auch "tar cvf /tmp/full-structure.tar * data.zip * info.txt" gaben mir 3 Fehler : (1) "tar: * data.zip: Kann nicht stat: Keine solche Datei oder Verzeichnis", (2) "tar * info.txt: Kann nicht stat: Keine solche Datei oder Verzeichnis", (3) "tar: Beenden mit Fehlerstatus aufgrund früherer Fehler ". Aus welchem ​​Ordner mache ich das alles? Ich verstehe diese Methode nicht.
user1271772
Die Frage sagt WINDOWS
Anfelipe
Win10 hat WSL, was dies gültig macht. Teer ist seit mehr als 20 Jahren unter Windows verfügbar und die Verwendung einer Pipe funktioniert seit den MS-DOS-Tagen. In jeder Shell-Umgebung ist die PWD wichtig. PWD - aktuelles Arbeitsverzeichnis. Ich gebe zu, diese Lösung ist weniger für Endbenutzer als für Power-User oder Programmierer.
JohnP
1
XCOPY /S folder1\data.zip copy_of_folder1  
XCOPY /S folder1\info.txt copy_of_folder1

BEARBEITEN: Wenn Sie die leeren Ordner beibehalten möchten (die Sie beim erneuten Lesen Ihres Beitrags scheinbar verwenden), verwenden Sie / E anstelle von / S.

gkrogers
quelle
1
Die Ordnerstruktur bleibt nicht erhalten.
Paulius
Die Option / E behält die Ordnerstruktur bei und erstellt bei Bedarf leere Ordner. Der Dateiname funktioniert auch mit einem Platzhalter (z. B. Ordner1 \ *. Zip). Ich erhalte den Fehler "Datei nicht gefunden" nur, wenn ich einen vollständigen Dateinamen übergebe, der nicht vorhanden ist (in diesem Fall wird "Datei nicht gefunden - xxx.xxx 0 Datei (en) kopiert" angezeigt. Wenn ich ihm ein Muster gebe das keine Dateien zurückgibt (zB Ordner1 \ *. zzz), ich bekomme nur "0 Datei (en) kopiert".
gkrogers
1

Über die WinRAR-Befehlszeilenschnittstelle können Sie die Dateinamen und / oder Dateitypen in ein Archiv kopieren. Dann können Sie dieses Archiv an einen beliebigen Ort extrahieren. Dadurch bleibt die ursprüngliche Dateistruktur erhalten.

Ich musste meinem Handy fehlende Albumbilddateien hinzufügen, ohne die Musik selbst erneut kopieren zu müssen. Glücklicherweise war die Verzeichnisstruktur auf meinem Computer und meinem Handy dieselbe!

Ich benutzte:

   rar a -r C:\Downloads\music.rar X:\music\Folder.jpg
  • C: \ Downloads \ music.rar = Zu erstellendes Archiv
  • X: \ music \ = Ordner mit Musikdateien
  • Folder.jpg = Dateiname, den ich kopieren wollte

Dadurch wurde ein Archiv mit allen Folder.jpg-Dateien in den entsprechenden Unterverzeichnissen erstellt.

Diese Technik kann auch zum Kopieren von Dateitypen verwendet werden. Wenn alle Dateien unterschiedliche Namen haben, können Sie alle Dateien in ein einziges Verzeichnis extrahieren. Zusätzliche Befehlszeilenparameter können mehrere Dateitypen archivieren.

Weitere Informationen finden Sie in diesem sehr hilfreichen Link http://cects.com/using-the-winrar-command-line-tools-in-windows/

Jim_Joat
quelle
0

Ich bin in Ordnung mit regulären Ausdrücken, faul und abgeneigt von Installationen, also habe ich eine Batch-Datei erstellt, die das Verzeichnis erstellt und mit Vanilla-DOS-Befehlen kopiert. Scheint mühsam, aber schneller für mich als das Ausarbeiten einer Robokopie.

  1. Erstellen Sie Ihre Liste der Quelldateien mit vollständigen Pfaden, einschließlich Laufwerksbuchstaben, falls erforderlich, in einer Textdatei.
  2. Aktivieren Sie reguläre Ausdrücke in Ihrem Texteditor.
  3. Fügen Sie bei Leerzeichen doppelte Anführungszeichen um jede Zeile ein - Suchzeichenfolge (.*)ersetzt Zeichenfolge"\1" und klicken Sie auf Alle ersetzen
  4. Erstellen Sie zwei Zeilen pro Datei - eine zum Erstellen des Verzeichnisses und eine zum Kopieren der Datei (qqq wird durch den Zielpfad ersetzt) ​​- Suchzeichenfolge (.*)Ersetzungszeichenfolgemd qqq\1\nxcopy \1 qqq\1\n und klicken Sie auf Alle ersetzen
  5. Entfernen Sie den Dateinamen aus den Zielpfaden - Suche \\([^\\^"]+)"\n ersetzen\\"\n
  6. Ersetzen Sie im Zielpfad (in diesem Beispiel A:\srcund B:\dest). Deaktivieren Sie reguläre Ausdrücke, suchen Sie qqq"A:\src\Ersetzen B:\dest\und klicken Sie auf Alle ersetzen.

md erstellt verschachtelte Verzeichnisse. copy würde sich in diesem Beispiel wahrscheinlich identisch mit xcopy verhalten. Möglicherweise möchten Sie / Y zu xcopy hinzufügen, um Überschreibbestätigungen zu unterdrücken. Sie erhalten eine Batch-Datei wie folgt:

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

wird für jede Datei in Ihrer ursprünglichen Liste wiederholt. Getestet auf Win7.

Chris
quelle
-1

Um dies mit Drag & Drop mit winzip zu tun, gibt es eine Option zum Beibehalten der Verzeichnisstruktur. Erstellen Sie einfach eine neue ZIP-Datei auf Verzeichnisebene, die Ihr Stammverzeichnis ist, und ziehen Sie die Dateien hinein.

Gnoy Dav
quelle
Vielen Dank, aber ich suchte nach einer Lösung für Skriptdateien (Batch-Dateien). Also kein Drag & Drop ...
M4N