2017-07-07 7 views
1

Je voulais copier un tas de fichiers jpg/gif avec le nom de départ dans un autre emplacement. Cela ne fonctionne pas comme prévu. Il crée des dossiers supplémentaires qui restent emtpy et ne copient pas tous les sous-dossiers. Ensuite, je cours de nouveau à travers le chemin entier et supprime tous les dossiers vides.powershell - Copy-Item crée un dossier vide

Comment puis-je empêcher Copy-Item de créer des dossiers vides supplémentaires? Je veux garder le chemin actuel avec une nouvelle racine et ajouter un nouveau sous-répertoire avec les lettres de début du nom de fichier et y mettre tous les fichiers.

structure de dossier en cours

F:\pics\2016\071310 
| 
-----> K001 
    | 
    ------> 0494434-002394 
    ------> 0494434-002394 
. 
. 
------> K0073 

voulait la structure des dossiers

C:\test\2016\071310 
| 
-----> K001 
    | 
    ------> 0494434-002394 
    | 
    ----> K-G 
    ----> K-F 
    . 
    . 
    ------> 0494434-002394 
    | 
    ----> K-G 
    ----> K-F 
    . 
    . 
. 
. 
------> K0073 

Voici mon code

$source = "F:\pics\2016\071310" 
$destination = "C:\test" 
$folder = "K-G\" 
$filterKG = [regex] "^K-G.*\.(jpg|gif)" 

$bin = Get-ChildItem -Exclude $folder -Path $source -Recurse | Where-Object {($_.Name -match $filterKG) -or ($_.PSIsContainer)} 

foreach ($item in $bin){ 
$new_folder = $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,$folder) 

if(-not (Test-Path $new_folder)){ 
    New-Item -Type dir $new_folder 
    Write-Host $new_folder 
} 
Copy-Item $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,$folder+$item.Name) 
} 

#remove empty folders which where added 
$tdc="C:\test" 
do { 
    $dirs = gci $tdc -directory -recurse | Where { (gci $_.fullName -Force).count -eq 0 } | select -expandproperty FullName 
    $dirs | Foreach-Object { Remove-Item $_ } 
} while ($dirs.count -gt 0) 
+1

Je ne comprends pas ce que vous voulez. Vous dites que vous voulez _ "conserver le chemin actuel avec une nouvelle racine et ajouter un nouveau sous-répertoire avec les lettres de début du nom de fichier et y mettre tous les fichiers". Mais la structure de dossier voulue ressemble aux fichiers copiés à la racine de la destination 'K001', et a des sous-répertoires vides' K-G' etc? – gms0ulman

+1

Dans le noyau je veux juste copier tous les fichiers commençant par K-G dans le dossier le plus profond dans un nouveau sous-dossier dans le sous-dossier le plus profond qui est nommé après les 3 premières lettres du fichier. –

Répondre

1

Script actuel

  • $_.PSIsContainer - Je pense que vous obtenez ceux-ci pour garder la structure des dossiers, mais mieux vaut les ignorer car vous n'êtes pas directement intéressé par eux. AFAICS c'est pourquoi vous obtenez des dossiers vides.
  • -Exclude $folder - Ceci ne fait rien; dossier avec le nom K-G sera toujours inclus.

  • $item.FullName.ToString() - Le ToString() ne fait rien car $item.FullName est déjà une chaîne. Exécutez $item.Fullname.GetType().Name pour voir.


Script proposé

  • Split-path vous permet d'obtenir le répertoire d'un fichier en utilisant -Parent.

  • .Replace($source,$destination) est comme dans votre script d'origine.

  • Vous n'avez pas besoin de coder en dur $folder pour l'obtenir dans votre destination. Utilisez simplement $item.Name.SubString(0,3) pour obtenir les 3 premières lettres d'un nom de fichier.
    string manipulation demo


$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filterKG)} 

foreach ($item in $bin){ 

    $new_folder = (Split-path $item.Fullname -Parent).Replace($source,$destination) + "\" + $item.Name.SubString(0,3) + "\" 

    if(-not (Test-Path $new_folder)){ 
     New-Item -Type dir $new_folder 
     Write-Host $new_folder 
    } 

    Copy-Item $item.FullName -Destination $new_folder 

}