I. Présentation
La commande PowerShell "Compare-Object" est très pratique pour comparer deux objets, comme deux variables, le contenu de deux fichiers ou encore le contenu entre deux dossiers. Il m'est arrivé à plusieurs reprises d'utiliser cette commande pour comparer deux fichiers CSV.
Lorsque l'on compare deux objets avec Compare-Object, la commande retourne :
- Les éléments identiques entre les deux fichiers
- Les éléments présent dans l'objet de référence, mais absent dans le second objet
- Les éléments absent dans l'objet de référence, mais présent dans le second objet
Vous l'aurez compris, dans ce tutoriel, je vais vous expliquer comment comparer deux objets en PowerShell avec Compare-Object.
II. Compare-Object : comparer deux chaînes de caractères
Compare-Object peut, tout simplement, comparer deux chaînes de caractères. Cela va nous permettre de bien appréhender la syntaxe de cette commande.
Pour comparer deux chaînes, il suffit de les préciser à la suite de Compare-Object :
Compare-Object "www.it-connect.fr" "IT-Connect"
Dans le cas où les chaînes sont égales, la commande ne va rien retourner. Si l'on veut inclure les éléments égaux, il faut ajouter le paramètre "-IncludeEqual".
Compare-Object "www.it-connect.fr" "WWW.IT-CONNECT.FR" -IncludeEqual
Comme on peut le constater avec cet exemple, la comparaison ne tient pas compte de la casse. Si elle est importante, on peut ajouter le paramètre "-CaseSensitive" pour tenir compte de la casse.
Compare-Object "www.it-connect.fr" "WWW.IT-CONNECT.FR" -IncludeEqual -CaseSensitive
Ce qui donne :
Suite à cette introduction, passons maintenant à un exemple beaucoup plus utile : la comparaison de fichiers CSV avec PowerShell et Compare-Object.
III. Compare-Object : comparer deux CSV
Prenons les deux fichiers CSV suivants :
Pays;
France;
Costa Rica;
Canada;
Belgique;
Suisse;
Pays;
France;
Costa Rica;
Espagne;
Belgique;
Islande;
Colombie;
Nous allons comparer ces deux fichiers pour identifier facilement les différences.
On va commencer par importer le contenu de nos fichiers CSV dans les variables $CSV1 et $CSV2.
$CSV1 = Import-CSV "C:\TEMP\CSV1.csv" -Delimiter ";"
$CSV2 = Import-CSV "C:\TEMP\CSV2.csv" -Delimiter ";"
Ensuite, nous allons comparer la variable $CSV1 et la variable $CSV2. Le fichier CSV1 sera notre objet de référence, on va l'associer au paramètre -ReferenceObject alors que l'objet de "différence" sera le fichier CSV2. Il faut également spécifier la propriété sur laquelle se baser pour faire la comparaison, ici ce sera notre colonne "Pays".
Ce qui donne :
Compare-Object -ReferenceObject $CSV1 -DifferenceObject $CSV2 -Property Pays
Le résultat suivant est obtenu :
La colonne "SideIndicator" permet de savoir de quel côté est présente la valeur :
- "=>" : fait référence à une valeur présente dans le -DifferenceObject (CSV2), mais absente dans le -ReferenceObject (CSV1)
- "<=" : fait référence à une valeur présente dans le -ReferenceObject (CSV1), mais absente dans le -DifferenceObject (CSV2)
Si l'on veut connaître seulement les valeurs présentes dans le fichier CSV1, mais absentes du fichier CSV2, on peut ajouter un filtre sur le SideIndicator :
Compare-Object -ReferenceObject $CSV1 -DifferenceObject $CSV2 -Property Pays | Where{ $_.SideIndicator -eq "<=" }
Pour l'inverse, il suffit de changer le sens de la flèche dans le filtre.
On peut également afficher seulement les valeurs communes entre les deux fichiers en ajoutant le paramètre -ExcludeDifferent pour exclure les valeurs différentes :
Compare-Object -ReferenceObject $CSV1 -DifferenceObject $CSV2 -Property Pays -ExcludeDifferent
Sachez qu'il est possible de comparer plusieurs colonnes, et pas uniquement une seule comme ici avec la colonne "Pays". Une ligne peut alors ressortir plusieurs fois (dans les deux sens) s'il y a la valeur d'une colonne qui change dans un fichier, mais pas dans l'autre.
Voici un exemple en image avec l'ajout de la colonne "Continent" dans nos fichiers CSV. Dans cet exemple, pour le pays "Colombie", la valeur du continent évolue entre les deux fichiers, donc la ligne ressort une fois dans le sens "=>" et une seconde fois dans l'autre sens "<=".
IV. Compare-Object : comparer le contenu de deux dossiers
Pour finir ce tutoriel, prenons un autre cas concret : comparer le contenu de deux dossiers. Le but : identifier les fichiers présents dans un dossier, mais pas dans l'autre.
Voici les deux dossiers qui servent de cobaye :
Commençons par récupérer la liste des éléments avec récursivité via la commande Get-ChildItem.
$DOSSIER1 = Get-ChildItem "C:\TEMP\DOSSIER1\" -Recurse
$DOSSIER2 = Get-ChildItem "C:\TEMP\DOSSIER2\" -Recurse
Ensuite, on utilise la commande Compare-Object sur le même principe que précédemment, sans spécifier de propriété.
Compare-Object -ReferenceObject $DOSSIER1 -DifferenceObject $DOSSIER2
On obtient directement les chemins complets vers les fichiers qui sont absents dans un dossier ou l'autre.
On peut également utiliser le paramètre -Property pour compare les dates de dernière modification des fichiers. Cela nécessite de lire l'attribut LastWriteTime. On ajoutera également le nom du fichier (pas le nom complet) pour ne pas que la sortie contienne seulement la valeur de LastWriteTime.
Compare-Object -ReferenceObject $DOSSIER1 -DifferenceObject $DOSSIER2 -Property Name,LastWriteTime -IncludeEqual
Ainsi, on peut identifier les fichiers les plus récents plus facilement grâce à ce différentiel.
Maintenant, c'est à vous de jouer ! N'hésitez pas à tester ces différents exemples et les commentaires sont là si vous avez une question
The post
PowerShell – Comparer des objets avec Compare-Object first appeared on
IT-Connect.