Come copiare una struttura di directory ma includere solo determinati file (utilizzando file batch di Windows)

StackOverflow https://stackoverflow.com/questions/472692

Domanda

Come dice il titolo, come posso copiare ricorsivamente una struttura di directory ma includere solo alcuni file. Ad esempio, data la seguente struttura di directory:

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

I file data.zip e info.txt possono apparire ovunque nella struttura della directory. Come posso copiare l'intera struttura di directory, ma includere solo i file denominati data.zip e info.txt (tutti gli altri file devono essere ignorati)?

La struttura di directory risultante dovrebbe apparire così:

copy_of_folder1
  folder2
    folder3
      data.zip
      info.txt
    folder4
    folder5
      data.zip
È stato utile?

Soluzione

Non menzionate se deve essere solo batch, ma se potete usare ROBOCOPY , provate questo:

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

EDIT: modificato il parametro / S in / E per includere cartelle vuote.

Altri suggerimenti

Una soluzione alternativa che copia un file alla volta e non richiede 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!"
    )
)

L'istruzione for esterna genera qualsiasi combinazione di percorso possibile della sottodirectory in SOURCE_DIR e il nome in FILENAMES_TO_COPY . Per ogni file esistente viene invocato xcopy. FILE_INTERMEDIATE_DIR contiene il percorso della sottodirectory del file all'interno di SOURCE_DIR che deve essere creato in DEST_DIR .

prova a reindirizzare l'output di find (cioè il percorso del file) in cpio

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

cpio controlla il timestamp sui file di destinazione, quindi è sicuro e veloce.

rimuovi -v per operazioni più veloci, una volta che ti ci abitui.

Se Powershell è un'opzione, puoi farlo:

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

Lo svantaggio principale è che copia tutte le cartelle, anche se finiranno per essere vuote perché nessun file corrisponde al filtro specificato. Quindi potresti finire con un albero pieno di cartelle vuote, oltre alle poche cartelle che hanno i file che desideri.

Grazie alle risposte precedenti. :)

Questo script chiamato " 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

Accetta variabili di " Origine " ;, " Destinazione " ;, e " FileName " ;. Può anche solo copiare tipi specifici di file o nomi di file selettivi.

Qualsiasi miglioramento è il benvenuto. :)

Solo con find e 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 ";"

Simile alla soluzione di Paulius, ma i file che non ti interessano non vengono copiati e quindi cancellati:

@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

Sono solo due semplici comandi, ma non lo consiglierei, a meno che i file che NON DEVI copiare siano piccoli. Questo perché questo copierà TUTTI i file e quindi rimuoverà i file non necessari nella copia.

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"

Certo, il secondo comando è piuttosto lungo, ma funziona!

Inoltre, questo approccio non richiede il download e l'installazione di strumenti di terze parti (Windows 2000+ BATCH ha abbastanza comandi per questo).

Sotto Linux e altri sistemi UNIX, l'uso del comando tar lo farebbe facilmente.

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

Quindi avresti cwd verso la destinazione e:

$ tar xvf /tmp/full-structure.tar 

Ovviamente è possibile reindirizzare l'output dal primo tar al secondo, ma vederlo funzionare a passi è più facile da capire e spiegare. Mi manca il cd / to / new / path / nel seguente comando: non ricordo come farlo adesso. Qualcun altro può aggiungerlo, si spera.

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

Tar (gnutar) è disponibile anche su Windows, ma probabilmente userò il metodo xcopy su quella piattaforma.

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

MODIFICA: Se vuoi preservare le cartelle vuote (che, rileggendo il tuo post, sembra che tu) usi / E anziché / S.

Utilizzando l'interfaccia della riga di comando di WinRAR, è possibile copiare i nomi dei file e / o i tipi di file in un archivio. Quindi puoi estrarre quell'archivio in qualsiasi posizione ti piaccia. Ciò preserva la struttura del file originale.

Avevo bisogno di aggiungere file di foto di album mancanti sul mio cellulare senza dover ricopiare la musica stessa. Fortunatamente la struttura delle directory era la stessa sul mio computer e sul mio cellulare!

Ho usato:

   rar a -r C:\Downloads\music.rar X:\music\Folder.jpg
  • C: \ Downloads \ music.rar = Archivio da creare
  • X: \ music \ = Cartella contenente file musicali
  • Folder.jpg = Nome file che volevo copiare

Questo ha creato un archivio con tutti i file Folder.jpg nelle relative sottodirectory.

Questa tecnica può essere utilizzata anche per copiare tipi di file. Se tutti i file avevano nomi diversi, è possibile scegliere di estrarre tutti i file in una singola directory. Ulteriori parametri della riga di comando possono archiviare più tipi di file.

Ulteriori informazioni in questo link molto utile http: // cects.com/using-the-winrar-command-line-tools-in-windows/

Per coloro che utilizzano Altap Salamander (file manager di 2 pannelli): nelle opzioni del popup Copia, basta specificare i nomi dei file o le maschere. Facile.

Sto bene con le espressioni regolari, pigre e avverse alle installazioni, quindi ho creato un file batch che crea la directory e le copia con i comandi DOS vanilla. Sembra laborioso ma più veloce per me che allenare robocopy.

  1. Crea il tuo elenco di file di origine con percorsi completi, inclusa la lettera di unità se nec, in un file di testo.
  2. Attiva le espressioni regolari nel tuo editor di testo.
  3. Aggiungi virgolette doppie attorno a ciascuna riga in caso di spazi: cerca la stringa (. *) sostituisci la stringa " \ 1 " e fai clic su Sostituisci tutto
  4. Crea due righe per file - una per creare la directory, una per copiare il file (qqq verrà sostituito con il percorso di destinazione) - cerca stringa (. *) sostituisci stringa md qqq \ 1 \ nxcopy \ 1 qqq \ 1 \ n e fai clic su Sostituisci tutto
  5. Rimuovi il nome file dai percorsi di destinazione & # 8211; cerca \\ ([^ \\ ^ "] +) " \ n sostituisci \\"\n
  6. Sostituisci nel percorso di destinazione (in questo esempio A: \ src e B: \ dest ). Disattiva le espressioni regolari, cerca qqq " A: \ src \ sostituisci B: \ dest \ e fai clic su Sostituisci tutto.

md creerà directory nidificate. la copia probabilmente si comporterebbe in modo identico a xcopy in questo esempio. Potresti voler aggiungere / Y a xcopy per sopprimere le conferme di sovrascrittura. Si finisce con un file batch in questo modo:

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

ripetuto per ogni file nell'elenco originale. Testato su Win7.

Per fare ciò con il trascinamento della selezione usa winzip c'è un'opzione di conservazione della struttura dir. Basta creare un nuovo .zip a livello di directory che sarà il tuo root e trascinare i file in.

Per copiare tutti i file di testo in G: e preservare la struttura delle directory:

xcopy *.txt /s G:
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top