Die PowerShell wird bunt

Eines meiner Lieblingsbücher (zur PowerShell) ist Monad von Andy Oakley (was nicht nur am Buchtitel liegt). Auf knapp 170 Seiten steht eigentlich alles Wichtige zur PowerShell  für den Einstieg drin, auch wenn das Buch noch aus der Zeit stammt wo die PowerShell noch Monad hieß (daher auch der Titel). Eines der kleinen Beispiele zeigt, wie sich per Get-ChildItem geholte Dateien in einem Verzeichnis in Abhängigkeit ihrer Dateierweiterung farbig ausgeben lassen.

Damals habe ich noch über diese Dinge gestaunt, heute (knapp 2 Jahre später) ist mir natürlich klar wie es funktioniert. Zu mindestens dachte ich es, als ich vor kurzem das Buch durchblätterte und auf das Beispiel stieß. Die Frage, die ich leider immer noch nicht beantworten kann ist, wie kann ich den Pipeline-Inhalt farbig ausgeben. Klar, Write-Host besitzt einen ForegroundColor-Parameter, doch wenn $_ für eine Datei (also ein FileInfo-Objekt) steht, führt ein

write-host -fore magenta $_

dazu, dass lediglich der Dateiname ausgegeben wird. In dem Buch von Andy Oakley wird die Ausgabe genauso durchgeführt, doch unter der damaligen Version der PowerShell scheint es wohl noch funktioniert zu haben. Meine Lösung ist daher etwas „uncool“, da sie Ausgabefarbe direkt über die Console-Klasse und ihre ForegroundColor-Property setzt:

# Verzeichniselemente farbig ausgeben

filter Farb-Dateien
{
  begin
  { $ForeColorOld = [Console]::ForegroundColor }
  process
  {
   $ExtFarben = @{ps1=“green“;txt=“yellow“;csv=“magenta“;html=“red“}
   $Farbe = „white“
   if ($_.Extension.Length -gt 1)
   {
     $Ext = $_.Extension.Substring(1)
     if ($ExtFarben.ContainsKey($Ext))
     { $Farbe = $ExtFarben[$Ext] }
   }
   [Console]::ForegroundColor = $Farbe
   $_
  }
  end
  { [Console]::ForegroundColor = $ForeColorOld }
}

Ein wenig uncool ist auch, dass die Farbe der Überschrift vom Typ des ersten Elements abhängt.

Ich bin inzwischen ein großer Fan davon, möglichst ohne den direkten Aufruf von .NET-Funktionen auszukommen. Allerdings wird eine solche Lösung gleich deutlich aufwändiger, da man sich nun auch um die Formatierung der Ausgabezeile kümmern muss, was dank dem -f-Operator aber sehr elegant geht:

# Verzeichniselemente farbig ausgeben

filter Farb-Dateien
{
  Begin
  { Write-Host -f magenta („{0}`t{1,-20}{2,-12}{3,-12}“ -f „Mode“,“Name“,“Länge“,“Letzer Zugriff“) }
  Process
  {
   $ExtFarben = @{ps1=“green“;txt=“yellow“}
   $Farbe = „white“
   if ($_.Extension.Length -gt 0 )

   {
    $Ext = $_.Extension.Substring(1)
    if ($ExtFarben.ContainsKey($Ext))
    {
     $Farbe = $ExtFarben[$Ext]
    }
   }
   $DateiAusgabe = „{0}`t{1,-20}{2,-12}{3,-12}“ -f $_.Mode,$_.Name,$_.Length,$_.LastAccessTime
   write-host -fore $Farbe $DateiAusgabe
  }
  End
  {
   Write-Host -fore Magenta „Zusammenfassung“
   Get-Childitem | Group-Object { $_.Extension } | foreach { „Erweiterung: {0,-10} Anzahl: {1,-8} “ -f $_.Name, $_.Count }
  }
}

Am Ende gebe ich sogar dank Group-Object eine Zusammenfassung aus.

Man muss lediglich wissen, dass man z.B. über ein {1,-20} ein auf 20 Zeichen linksbündig justierte Ausgabe erhält und sich damit das Hantieren mit Tabulatoren spart (das erfährt man aus der .NET-Referenz). Ich habe also was die PowerShell angeht seit dem ich das Buch von Andy Oakley gelesen hatte einiges dazu gelernt, 100% zufrieden bin ich mit meinem PowerShell-Know-how aber noch nicht (ansonsten käme ich darauf, wie man ein FileInfo-Objekt mit Write-Host ausgibt, ohne es selber formatieren zu müssen – sofern es dafür wirklich eine Lösung gibt).

PowerShellBunt
(PowerShell 1.0 – auf Wunsch auch bunt)

Schreibe einen Kommentar

Bitte logge dich mit einer dieser Methoden ein, um deinen Kommentar zu veröffentlichen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s