Comparaison de dossiers et de contenu avec PowerShell
PowerShell noob ici.
J'ai deux dossiers différents avec des fichiers xml. Un dossier (dossier2) contient des nouvelles et mises à jour des fichiers xml par rapport à l'autre (dossier1). J'ai besoin de savoir quels fichiers dans dossier2 sont neufs/mis à jour par rapport à folder1 et les copier sur un troisième dossier (dossier3). Quelle est la meilleure façon d'accomplir ceci dans PowerShell?
- Vous souhaitez comparer basé sur la date de modification ou voulez-vous comparer le contenu du fichier?
- Je veux comparer basé sur le contenu du fichier.
- Et comment voulez-vous gérer les fichiers qui n'existent pas dans l'un ou l'autre dossier?
- Si les fichiers n'existent pas dans dossier1, mais n'existe pas dans dossier2, alors que ces fichiers sont de nouveau et je veux les copier sur dossier3. Si les fichiers existent dans dossier1, mais n'existent pas dans dossier2, puis ceux-ci sont obsolètes les fichiers donc je ne veux pas de copier, mais ne les connecter entre eux.
- Et comment savez-vous un fichier qui est nouveau, basé sur le contenu? Si le fichier est dans les deux
folder1
etfolder2
mais les contenus sont différents, puis prendre l'un defolder2
, sinon ignorer si elles sont de la même? - Je sais qu'un fichier est nouveau, uniquement basée sur le fait que c'est dans dossier2 et pas dans folder1 comme folder2 est une version mise à jour de dossier1. Et oui, si le même fichier est dans les folder1 et dossier2, mais le contenu de ce fichier est différent dans dossier2, puis de la copier, sinon ignorer si les fichiers sont les mêmes.
- Comment voulez-vous gérer des fichiers avec le contenu en double, mais des noms de fichiers différents?
Vous devez vous connecter pour publier un commentaire.
OK, je ne vais pas le code de la chose entière pour vous (ce qui est le plaisir dans tout cela?) mais je vais vous aider à démarrer.
Tout d'abord, il y a deux façons de faire du contenu de la comparaison. Le paresseux/surtout le droit chemin, qui est la comparaison de la longueur des fichiers; et le précis, mais plus impliqués, qui est la comparaison d'un hachage du contenu de chaque fichier.
Par souci de simplicité, nous allons faire la voie de la facilité et de comparer la taille du fichier.
Fondamentalement, vous avez besoin de deux objets qui représentent la source et la cible des dossiers:
Ensuite, vous pouvez utiliser
Compare-Object
pour voir les éléments qui sont différents...Compare-Object $Folder1 $Folder2 -Property Name, Length
qui liste pour vous tout ce qui est différent de comparer uniquement le nom et la longueur de la file d'objets dans chaque collection.
Vous pouvez tuyau à un
Where-Object
filtre à ramasser des trucs qui est différent sur le côté gauche...Compare-Object $Folder1 $Folder2 -Property Name, Length | Where-Object {$_.SideIndicator -eq "<="}
Et puis la pipe que pour un
ForEach-Object
pour copier où vous voulez:Compare-Object $Folder1 $Folder2 -Property Name, Length | Where-Object {$_.SideIndicator -eq "=>"} | ForEach-Object {Copy-Item "$Folder2Path\$($_.name)" -Destination $Folder3 -Force}
-property name
et d'inverser le côté de l'indicateur, puis connectez-vous ou ce que vous voulez.Get-Childitem "C:\Folder2" | where-object {$_.length -eq $null}
pour obtenir les dossiers uniquement. Vous pouvez ensuite tuyau d'ailleurs. Si vous avez besoin de faire beaucoup de ce qu'il peut faire sens pour en faire une fonction qui vous nourrissez des dossiers, alors vous pouvez le faire récursif pour traiter les sous-dossiers automatiquement.-recurse
à la Get-childitem appelsRécursive Répertoire Diff en Utilisant le Hachage MD5 (Compare le Contenu)
Ici est un pur PowerShell v3+ récursive de fichiers diff (pas de dépendances) qui calcule le hachage MD5 pour chacun des répertoires contenu du fichier (gauche/droite). Pouvez éventuellement exporter CSV avec un résumé fichier texte. Par défaut il affiche les résultats sur la sortie standard stdout. Pouvez soit laisser tomber le rdiff.ps1 fichier dans votre chemin d'accès ou copier le contenu dans votre script.
USAGE: rdiff path/to/left,path/to/right [-s path/to/summary/dir]
Ici est la gist. Recommandé d'utiliser la version de gist, car elle peut avoir des fonctionnalités supplémentaires au fil du temps. N'hésitez pas à envoyer pull requests.
Encore à @JNK réponse, vous pourriez vouloir vous assurer que vous êtes toujours en train de travailler avec des fichiers plutôt que de la moins-intuitif de sortie de
Compare-Object
. Vous avez juste besoin d'utiliser le-PassThru
interrupteur...Ce qui signifie que vous n'avez pas à vous soucier de la façon dont le SideIndicator flèche points!
Aussi, gardez à l'esprit que vous voudrez peut-être comparer sur LastWriteTime ainsi.
Sous-dossiers
En parcourant les sous-dossiers de manière récursive est un peu plus compliqué, car vous aurez probablement besoin d'enlever la racine respectifs dossier chemins d'accès dans le champ Nom complet, avant de comparer les listes.
Vous pouvez le faire par l'ajout d'un nouveau ScriptProperty à votre Folder1 et Folder2 listes:
Vous devriez alors être en mesure d'utiliser RelativePath comme une propriété lorsque l'on compare les deux objets et également l'utiliser pour se joindre à des "C:\Folder3" lors de la copie de conserver la structure du dossier en place.
$Folder2 = "C:\Folder3\"
cela pourrait être$Folder3 = "C:\Folder3\"
Pratique version en utilisant le paramètre de script
Simple au niveau des fichiers comparasion
L'appeler comme
PS > .\DirDiff.ps1 -a .\Old\ -b .\New\
De sortie possibles:
Ce faire:
Et même de manière récursive:
et est même difficile de l'oublier 🙂
dcg -chemin "C:\Folder' -recurse |where{$_.PSIsContainer}
-recurse à explorer toutes les sous-rubriques ci-dessous la racine du chemin d'accès donné et la .PSIsContainer de propriété est celui que vous voulez tester pour saisir tous les dossiers uniquement. Vous pouvez l'utiliser où{!$_.PSIsContainer} pour que les fichiers.