Come copiare una struttura di directory ma includere solo determinati file (utilizzando file batch di Windows)
-
19-08-2019 - |
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
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.
- Crea il tuo elenco di file di origine con percorsi completi, inclusa la lettera di unità se nec, in un file di testo.
- Attiva le espressioni regolari nel tuo editor di testo.
- Aggiungi virgolette doppie attorno a ciascuna riga in caso di spazi: cerca la stringa
(. *)
sostituisci la stringa" \ 1 "
e fai clic su Sostituisci tutto - 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 stringamd qqq \ 1 \ nxcopy \ 1 qqq \ 1 \ n
e fai clic su Sostituisci tutto - Rimuovi il nome file dai percorsi di destinazione & # 8211; cerca
\\ ([^ \\ ^ "] +) " \ n
sostituisci\\"\n
- Sostituisci nel percorso di destinazione (in questo esempio
A: \ src
eB: \ dest
). Disattiva le espressioni regolari, cercaqqq " A: \ src \
sostituisciB: \ 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: