Get-Childitem est une commande Powershell permettant de récuperer l'intégralité des fichiers et dossiers dans un répertoire, et ce de manière récursive. Afin de connaître l'origine des problèmes d'espace disque sur notre partie NAS, j'ai crée un script utilisant Get-Childitem pour obtenir la taille de l'espace personnel de chaque utilisateur, et en ressortir les 3 fichiers les plus imposants.
Seul problème, certains repertoires étant profondéments ancrés dans une hierarchie tentaculaire de dossiers et sous-dossiers, leur nom complet devenait extrêmement long, et Powershell -qui rappelons-le, se base sur .NET- est limité à une longueur de 260 caractères sur le chemin complet.
Pour contourner cela et obtenir la liste complète des fichiers, il faut utiliser un outil bien connu dans le monde de la copie windows, ROBOCOPY.
En utilisant cet outil intégré dans Windows 7, nous pouvons obtenir une liste de fichiers via un outil n'utilisant pas .NET, et outrepassant donc cette limitation à 260 caractères.
Le problème de ROBOCOPY est que son format de retour est une chaîne de texte difficilement exportable sous format tableau. Nous allons donc utiliser les Expressions Regulières (REGEX) pour formater chaque ligne et la séparer de manière intelligente. Tout d'abord, voici un format de ligne renvoyé par ROBOCOPY.
Nous voyons qu'il y'a une série d'espaces, suivi de la taille du fichier, la date, un espace, l'heure, une série d'espaces, le nom du fichier (pouvant comporter un nombre indéfini d'espaces et de caractères divers).
Et voici la REGEX correspondante pour hacher proprement , que j'expliquerais ensuite.
$files[30] -match "\d+\s\S+\s\S+\s+.*$"
Attendez avant de prendre une aspirine! Je sais que cela semble particulièrement imbuvable, mais vous allez voir qu'en fait, les expressions régulières sont à la fois faciles à comprendre et puissantes!
Chaque lettre signifie quelque chose. Dans cette expression nous avons :
Et quand au + et * ?!
Et bien ce sont les symboles qui précisent le nombre d'itérations que l'on doit trouver sur l'objet accolé. Le + signifie "une occurence ou plus" et le * "zéro occurence ou plus". Il est tout à fait possible de préciser un nombre d'itérations, en les mettant entre crochets, par exemple \d{2}.
Si l'on reprend notre format de ligne renvoyé par Robocopy, nous constatons effectivement que nous avons \d+ (un nombre de chiffres indéfini) suivi d'un \s (espace), puis \S+ pour des caractères non vides , de nouveau \s+ pour un nombre inconnu d'espaces, et enfin le restant .*$ , n'importe quel caractère jusqu'a la fin de la ligne.
Bon, maintenant que nous savons comment hacher cela, comment récuperer les informations? Et bien c'est simple... lorsque l'on se sert de l'opérateur -Match , les résultats valides de l'expression sont sauvegardés dans une variable nommée $Matches, comme ici :
Mais cet affichage n'est pas vraiment interessant, car il ne nous renvoie que l'intégralité de la correspondance du REGEX. Comment pouvons-nous donc différencier le tout? Par le biais d'une syntaxe spécifique, de ce format :
(?<nombre>\d{2})
Dans cet exemple, nous enregistrerons dans "nombre" les deux chiffres à l'emplacement donné. Reprenons l'exemple ci dessus, mais en enregistrant cette fois ci la découpe du REGEX, grace à l'expression suivante :
"(?<premier>\w+)\s(?<deuxieme>\w+)"
Observons maintenant le résultat dans $Matches :
Et désormais c'est très facile d'appeler une partie de la découpe du REGEX :
Maintenant, en appliquant cela à notre exemple de Robocopy, nous pouvons facilement detecter la taille, la date du fichier, ainsi que son chemin complet, à l'aide d'une REGEX pour laquelle, j'en suis persuadé ( :) ) , vous trouverez aisément la signification :
"(?<taille>\d+)\s(?<date>\S+\s\S+)\s+(?<chemin>.*$)"
Voici la réponse, pour celles et ceux qui n'auraient pas deviné :
Vous êtes désormais capable de dépasser cette limitation de caractères ennuyeuse venant du .NET ! Pour une documentation plus complète des quantifieurs et des classes de caractères pour les Regex, une seule direction : MSDN! Et comme personne n'aime chercher, voici les liens pour vous!