2010-04-30 25 views
1

Laissez-moi vous expliquer ma question. J'ai un rapport quotidien d'environ un espace libre PC comme dans le fichier texte (sp.txt) comme:Powershell: Select-Object avec valeur de différence calculée supplémentaire

DateTime  FreeSpace(MB) 
-----   ------------- 
03/01/2010  100.43 


DateTime  FreeSpace(MB) 
-----   ------------- 
03/02/2010  98.31 

.... 

Puis-je utiliser ce fichier comme entrée pour générer un rapport avec une différence d'espace libre entre les dates:

DateTime  FreeSpace(MB) Change 
-----   ------------- ------ 
03/01/2010  100.43 
03/02/2010  98.31   2.12 
.... 

Voici quelques codes que je dois obtenir au-dessus résultat sans le calcul du « changement » supplémentaire:

Get-Content "C:\report\sp.txt" ` 
| where {$_.trim().length -gt 0 -and -not ($_ -like "Date*") -and -not ($_ -like "---*")} ` 
| Select-Object @{Name='DateTime'; expression={[DateTime]::Parse($_.SubString(0, 10).Trim())}}, ` 
    @{Name='FreeSpace(MB)'; expression={$_.SubString(12, 12).Trim()}}, ` 
| Sort-Object DateTime ` 
| Select-Object DateTime, 'FreeSpace(MB)' |ft -AutoSize # how to add additional column Change to this Select-Object? 

Ma compréhension est que Select-Object retourne une collection d'objets . Ici, je crée cette collection à partir d'un fichier texte d'entrée (analyser chaque ligne en parties: datetime et freespace (MB)). Pour calculer la différence entre les dates, je suppose que j'ai besoin d'ajouter une valeur calculée au résultat du dernier Select-Object, ou de diriger le résultat vers un autre Select-Object avec le calcul comme propriété ou colonne additionnelle . Pour ce faire, j'ai besoin de la valeur FreeSpace de la ligne précédente. Vous ne savez pas si c'est possible et comment?

Répondre

2

Je pense que cela devrait fonctionner. Je viens de le dérouler en une seule boucle où nous gardons trace de la dernière valeur et l'utilisons pour créer la propriété change dans l'expression select. J'ai également modifié légèrement le code d'analyse afin que vous ne dépendiez pas de longueurs de sous-chaînes codées en dur. Cela a également aidé à rendre les expressions sélectionnées plus faciles à écrire et à comprendre.

Get-Content "sp.txt" ` 
| where {$_.trim().length -gt 0 -and -not ($_ -like "Date*") -and -not ($_ -like "---*")} ` 
| %{ 
    $row = (-split $_); 
    $obj = select-object -input $row -prop @{Name='DateTime'; expression={[DateTime]($row[0]);};} , ` 
         @{Name='FreeSpace(MB)'; expression={[Double]($row[1]);} }, ` 
         @{Name='Change'; expression={if($last){$row[1]-$last.'FreeSpace(MB)'}else{0}}}; 
    $last = $obj; 
    $obj; 
    } | sort DateTime | ft -autosize 
+0

rapide commentaire ici, pour garder ma question simple, j'ai utilisé datetime comme date seulement. La valeur réelle est la date et l'heure, donc il y a un espace entre la date, l'heure et am/pm comme '03/01/2010 02:34:00 AM ".En tout cas, je vais essayer et digérer votre solution. Merci @zdan! –

+0

comment formater la valeur de changement à quelque chose comme '0: N2' -f, soit 2 chiffres après la virgule? Certaines valeurs sont comme 0.18223233.Je voudrais que la valeur de changement à 0.18 –

+0

Pour mettre en forme le résultat en tant que valeur avec deux chiffres, utilisez simplement une variable temporaire telle que $ v pour contenir la valeur if et else, puis renvoyez '{0: N2}' -f $ v à la fin du bloc if else. –

Questions connexes