Batchfil för att kopiera mappstruktur

Permalänk
Mattecoach

Batchfil för att kopiera mappstruktur

Hej,

Jag har följande problem:
Det finns en mappstruktur med flera undermappar i flera nivåer. Nu vill jag att det i varje mapp ska finnas en viss struktur. Ex.:

Mapp A Mapp AA Mapp AB Mapp AC Mapp B Mapp BA Mapp BB Mapp BC Mapp C osv

I hela denna struktur ska det finnas samma fyra mappar på samtliga nivåer.
Jag hittade ett exempel med en batchfil som jag har försökt att redigera, som ser ut som följer:

for /l %%a in (1,1,5) do ( call :Method1 ) :Method1 FOR /D %%a in ("C:\Temp1\*") do xcopy "C:\New folder\*.*" "%%a" /c /y /e /t GOTO :EOF

Där "Temp1" är foldern som jag vill "fylla" och "New Folder" är mappen som innehåller strukturen.

Mitt problem är helt enkelt att det inte fungerar, och jag vet inte hur man felsöker!
Någon som kan hjälpa mig? Tack på förhand!

Mvh
Daniel

Permalänk
Legendarisk

@PuMaH: Får erkänna att jag inte helt förstår vad du vill åstadkomma, men kodsnutten du har hittat hoppar först till :Method1 5 gånger (och gör samma sak varje gång), och när den är klar faller den igenom och passerar det stycket en gång extra (så totalt försöker den köra nästa loop 6 gånger, för att undvika det behövs en extra goto efter din första loop). Nästa loop borde inte fungera alls, gissar att du får ett felmeddelande om just det, och antingen bör du ha kommandot på samma rad direkt efter DO, eller omge de rader som ska köras med parenteser:

FOR /D %%A in ("C:\Temp1\*") DO ECHO %%A


FOR /D %%A in ("C:\Temp1\*") DO ( ECHO %%A )

För att minska på allt brus kan du inleda ditt script med @ECHO OFF eller placera ett @ framför de kommandon du inte vill skriva ut som de är till terminalen. Exemplet nedan kommer bara skriva ut filnamnen i C:\Temp1:

@ECHO OFF FOR /D %%A in ("C:\Temp1\*") DO ECHO %%A


@FOR /D %%A in ("C:\Temp1\*") DO @ECHO %%A

Förstår dock inte riktigt syftet med att anropa xcopy så, annat än att du vill ha alla mappar (men inga filer?) kopierade från en mallstruktur till en ny destination? Det vore lättare att använda PowerShell än att scripta för mycket i Batch, det har funnits med Windows sedan XP och man bör försöka lösa sådana här problem med det hellre än gamla Batch nuförtiden.

Här är ett exempel som kanske gör vad du behöver. Det listar först alla mappar i din källa (.\Template\ i exemplet), sedan kopierar det varje mapp och inkluderar dess innehåll (men bara mappar) till destinationen (.\Target\ i exemplet). (Parametern -WhatIf gör att Copy-If skriver ut en beskrivning av operationen istället för att faktiskt göra något, ta bort den för att köra koden).

Get-ChildItem -Path .\Template\ -Directory | %{ Copy-Item -Path $_.FullName -Destination .\Target\ -Filter {PSIsContainer} -Recurse -WhatIf }

Källa: Template ├─ A │ ├─ D │ ├─ E │ └─ Text.txt ├─ B └─ C Destination före: Target └─ <tom> Destination efter: Target ├─ A │ ├─ D │ └─ E ├─ B └─ C

Alternativt, med bara xcopy (som går att anropa från både Batch och PS):

XCOPY "C:\Template" "C:\Target" /E /T

Visa signatur

Abstractions all the way down.

Permalänk
Mattecoach

@Biberu:

Tack för svaret!

Jag tror att du har svarat på det jag vill, men tvärt om.
Jag har fyra mappar, som jag vill kopiera in i alla mappar i en viss strukur. Loopen var menad att gå igenom hela strukturen (kopiera de fyra mapparna till A, kopiera de fyra mapparna till AA, kopiera till AB, osv.). De fyra mapparna som jag vill kopiera är tomma, det är alltså bara mappar och inga filer som ska kopieras.
Det jag gör nu är alltså att kopiera de fyra mapparna, gå in i en "destination", klistra in, gå in i nästa, klistra in, osv.

Jag har inte skrivit detta själv, utan använde ett exempel som jag hittade.
https://stackoverflow.com/questions/11339403/copying-a-folder...

Han vill göra samma sak, men flytta filer istället för mappar.

Hoppas att jag lyckades förtydliga!

Permalänk
Legendarisk

@PuMaH:

@ECHO OFF FOR /D %%A IN ("C:\Target\*") DO ( XCOPY "C:\Template" "%%A" /E /T )

Källa: Template ├─ A │ ├─ D │ ├─ E │ └─ Text.txt ├─ B └─ C Destination före: Target ├─ T_A └─ T_B Destination efter: Target ├─ T_A │ ├─ A │ │ ├─ D │ │ └─ E │ ├─ B │ └─ C └─ T_B ├─ A │ ├─ D │ └─ E ├─ B └─ C

På det viset?

Visa signatur

Abstractions all the way down.

Permalänk
Mattecoach

@Biberu: Ja, det är så det är tänkt!

Tack för hjälpen, testar imorgon!

Permalänk
Mattecoach

@Biberu:

Tack, det funkade!
Men... Bara på första nivån. Detta är fortfarande en stor hjälp, men det skulle underlätta enormt om det också går att kopiera in i undermappar i målet. Se nedan.

Källa: Template ├─ A │ ├─ D │ ├─ E │ └─ Text.txt ├─ B └─ C Destination före: Target ├─ T_A │ └─ T_AB └─ T_B Destination efter: Target ├─ T_A │ ├─ A │ │ ├─ D │ │ └─ E │ ├─ B │ └─ C │ └─T_AB └─ T_B ├─ A │ ├─ D │ └─ E ├─ B └─ C Önskat läge: Target ├─ T_A │ ├─ A │ │ ├─ D │ │ └─ E │ ├─ B │ └─ C │ └─T_AB │ ├─ A │ │ ├─ D │ │ └─ E │ ├─ B │ └─ C └─ T_B ├─ A │ ├─ D │ └─ E ├─ B └─ C

Permalänk
Legendarisk

@PuMaH: Tyvärr vet jag inte om det finns någon snabb lösning för det i Batch, men i PowerShell kan du göra så här:

# Ta fram en lista av alla befintliga mappar och undermappar i destinationen, # spara den i $targetFolders så att kopieringsprocessen inte i sig skapar fler mål...: $targetFolders = Get-ChildItem -Path .\Target\ -Directory -Recurse # För varje mapp i listan: $targetFolders | %{ $targetFolder = $_.FullName # Hitta varje mapp i källan / mallen... Get-ChildItem -Path .\Template\ -Directory | %{ $sourceFolder = $_.FullName # ... och kopiera den samt alla undermappar till den aktuella destinationsmappen: Copy-Item -Path $sourceFolder -Destination $targetFolder -Filter {PSIsContainer} -Recurse } }

Visa signatur

Abstractions all the way down.

Permalänk
Mattecoach

@Biberu: Och här ju problemet att jag aldrig har använt PowerShell...

Permalänk
Legendarisk

@PuMaH: Om du skapar en mapp med den här strukturen:

</Ditt/Projekt> ├─ Target │ ├ T_A │ │ └─ T_B │ └ T_C ├─ Template │ ├─ A │ │ └─ B │ └─ C └ Test.ps1 <- Spara scriptexemplet här

Starta sedan PowerShell som administratör och kör följande kommando för att tillåta exekvering av lokala scripts. Det här steget behöver du bara göra första gången, inställningen ligger kvar efteråt. Se den här sidan för mer information om det.

PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

Efteråt kan du nagivera till /Ditt/Projekt och köra scriptet så här:

PS C:\Ditt\Projekt> ./Test.ps1 # obs. ./ framför filnamnet

Visa signatur

Abstractions all the way down.

Permalänk
Mattecoach

@Biberu: Har följt det du har skrivit, men får det inte att fungera.
Har lagt mina mappar Target och Template i C:\Temp1 tillsammans med Script.ps1.

PS C:\> cd Temp1 PS C:\Temp1> ./Script.ps1 Get-ChildItem : A parameter cannot be found that matches parameter name 'Directory'. At C:\Temp1\Script.ps1:3 char:59 + $targetFolders = Get-ChildItem -Path .\Target\ -Directory <<<< -Recurse + CategoryInfo : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand Get-ChildItem : A parameter cannot be found that matches parameter name 'Directory'. At C:\Temp1\Script.ps1:10 char:48 + Get-ChildItem -Path .\Template\ -Directory <<<< | %{ + CategoryInfo : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

Permalänk
Legendarisk

@PuMaH: Den växeln är ny i PowerShell 3.0 (Windows 8, eller Windows 7 via separat installation (senaste versionen är 5.1 och Windows 7 är 8 år gammalt nu)), kör du något äldre än det? Du kan i.v.f. arbeta runt det genom att filtrera ut mappar manuellt på det här sättet:

# Pipe:a listan till ett filter som bara sparar mappar: $targetFolders = Get-ChildItem -Path .\Target\ -Recurse | ?{ $_.PSIsContainer } $targetFolders | %{ $targetFolder = $_.FullName Get-ChildItem -Path .\Template\ | ?{ $_.PSIsContainer } | %{ $sourceFolder = $_.FullName Copy-Item -Path $sourceFolder -Destination $targetFolder -Filter {PSIsContainer} -Recurse } }

Visa signatur

Abstractions all the way down.

Permalänk
Mattecoach

@Biberu: Borde såklart nämnt det, kör Windows 7 Enterprise.

Jag fick nu en hel radda felmeddelanden (tydligen hade jag redan några av mapparna på plats). Jag rensade ut allt och körde igen, då fungerade det klockrent!

Tusen tack för hjälpen! Du har sparat mig några timmars arbete (denna gången, mer då jag troligtvis kommer göra något liknande igen).

Permalänk
Legendarisk

@PuMaH: Np, trevligt att du fick ordning på det.

Visa signatur

Abstractions all the way down.