53 votes

Comment utiliser PowerShell copy-item et garder la structure

J'ai une structure de répertoire qui ressemble à ceci :

C:\folderA\folderB\folderC\client1\f1\files
C:\folderA\folderB\folderC\client1\f2\files
C:\folderA\folderB\folderC\client2\f1\files
C:\folderA\folderB\folderC\client2\f2\files
C:\folderA\folderB\folderC\client3\f1\files
C:\folderA\folderB\folderC\client4\f2\files

Je veux copier le contenu du f1 dossiers dans C:\tmp\ pour obtenir ce

C:\tmp\client1\f1\files
C:\tmp\client2\f1\files
C:\tmp\client3\f1\files

J'ai essayé ça :

Copy-Item -recur -path: "*/f1/" -destination: C:\tmp\

Mais il copie le contenu sans copier correctement la structure.

5voto

Rafael Costa Points 163

J'ai donc passé du temps à trouver un moyen plus simple qui n'implique pas de piping ou de script en ligne :

Copy-Item -Path $sourceDir -Destination $destinationDir -Recurse -Container -Verbose

On peut également fournir un -Filter argument si une condition pour la copie est demandée.

Fonctionne avec PowerShell 5.1.18362.752.

Source : https://devblogs.microsoft.com/scripting/powertip-use-powershell-to-copy-items-and-retain-folder-structure/

4voto

mjsr Points 1781

El Container (vers Copy-Item) permet de conserver la structure du dossier. Profitez-en.

testing>> tree

Folder PATH listing
Volume serial number is 12D3-1A3F
C:.
client1
   f1
      files
   f2
       files
client2
   f1
      files
   f2
       files
client3
   f1
       files
client4
    f2
        files

testing>> ls client* | % {$subdir = (Join-Path $_.fullname f1); $dest = (Join-Path temp ($_
.name +"\f1")); if(test-path ($subdir)){ Copy-Item $subdir $dest -recurse -container -force}}

testing>> tree

Folder PATH listing
Volume serial number is 12D3-1A3F
C:.
client1
   f1
      files
   f2
       files
client2
   f1
      files
   f2
       files
client3
   f1
       files
client4
   f2
       files
temp
    client1
       f1
           files
    client2
       f1
           files
    client3
        f1
            files

testing>>

1voto

mik-T Points 916

J'avais besoin de faire la même chose, alors j'ai trouvé cette commande :

XCopy souce_path destination_path /E /C /I /F /R /Y

Et dans votre cas :

XCopy c:\folderA\folderB\folderC c:\tmp /E /C /I /F /R /Y

Et si vous avez besoin d'exclure certains éléments, créez un fichier texte avec une liste d'exclusions. Par exemple :

Créez un fichier texte 'exclude.txt' sur le disque C:\ et ajoutez-y ceci :

.svn
.git

Et votre commande de copie ressemblera à ceci maintenant :

XCopy c:\folderA\folderB\folderC c:\tmp /EXCLUDE:c:\exclude.txt /E /C /I /F /R /Y

0voto

gladiator Points 764

Le texte ci-dessous a fonctionné pour moi

@echo off
    setlocal enableextensions disabledelayedexpansion

    set "target=e:\backup"

    for /f "usebackq delims=" %%a in ("TextFile.txt") do (
        md "%target%%%~pa" 2>nul
        copy /y "%%a" "%target%%%~pa"
    )

Pour chaque ligne (fichier) à l'intérieur de la liste, créez, sous le dossier cible, le même chemin indiqué dans la ligne de lecture (%%~pa est le chemin de l'élément référencé par %%a). Ensuite, copiez le fichier lu dans le dossier cible.

0voto

$sourceDir = 'C:\source_directory'
$targetDir = 'C:\target_directory'

Get-ChildItem $sourceDir -Recurse | % {
   $dest = $targetDir + $_.FullName.SubString($sourceDir.Length)

   If (!($dest.Contains('.')) -and !(Test-Path $dest))
   {
        mkdir $dest
   }

   Copy-Item $_.FullName -Destination $dest -Force
}

Ce code fonctionne, surtout si vous utilisez Get-ChildItem en liaison avec une méthode de filtre/objet.

Cependant, il y a une petite erreur dans ce code : Par l'instruction "IF" et le code suivant "mkdir" le dossier sur le $targetDir sera créé...ensuite la commande "copy-item" crée le même dossier dans le dossier qui vient d'être créé par la commande "mkdir".


Voici un exemple de la façon dont cela a fonctionné pour moi avec une fonction "Where-Object". Vous pouvez simplement omettre l'instruction IF.

$Sourcefolder= "C:\temp1"
$Targetfolder= "C:\temp2"

$query = Get-ChildItem $Sourcefolder -Recurse | Where-Object {$_.LastWriteTime -gt [datetime]::Now.AddDays(-1)}
$query | % {
    $dest = $Targetfolder + $_.FullName.SubString($Sourcefolder.Length)
    Copy-Item $_.FullName -Destination $dest -Force
}

Assurez-vous que les chemins ne sont pas indiqués par un "\" à la fin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X