2009-09-13 8 views
2

Contextefaire TextWrap et dedent dans Windows Powershell (ou dotNet alias .net)

Python a "TextWrap" et fonctions "dedent". Ils font à peu près ce que vous attendez de toute chaîne que vous fournissez.

textwrap.wrap (texte [, largeur [, ...]])

Wraps le seul paragraphe dans le texte (une chaîne) de sorte que chaque ligne est au plus largeur des caractères de long. Renvoie une liste de lignes de sortie, sans les nouvelles lignes finales.

textwrap.dedent (texte)

Retirez tout les espaces au commun de chaque ligne dans le texte.

http://docs.python.org/library/textwrap.html

Question:

Comment faites-vous cela dans Windows PowerShell (ou avec des méthodes .NET que vous appelez de PowerShell)?

Répondre

1

Je pense que vous devriez créer un utilitaire CLI avec ce comportement et le personnaliser comme vous le souhaitez. Et puis utilisez-le comme une commande dans votre shell. Peut-être que vous devrez également ajouter votre script dans PATH.

3

Ce code fait preuve de négligence ...

#requires -version 2.0 
    function wrap([string]$text, [int]$width) { 
    $i=0; 
    $text.ToCharArray() | group { [Math]::Floor($i/$width); (gv i).Value++ } | % { -join $_.Group } 
} 

function dedent([string[]]$text) { 
    $i = $text | % { $_ -match "^(\s*)" | Out-Null ; $Matches[1].Length } | sort | select -First 1 
    $text -replace "^\s{$i}" 
} 
1

En regardant les résultats en python à http://try-python.mired.org/, il semble que l'algorithme correct se divise à des limites de mots, plutôt que de prendre des sous-chaînes de longueur fixe du texte.

function wrap([string]$text, [int]$width = 70) { 
    $line = '' 

    # Split the text into words. 
    $text.Split(' '.ToCharArray()) | % { 
    # Initialize the first line with the first word. 
    if(-not $line) { $line = $_ } 
    else { 
     # For each new word, try to add it to the current line. 
     $next = $line + ' ' + $_ 

     # If the new word goes over the limit, 
     # return the last line and start a new one. 
     if($next.Length -ge $width) { $line; $line = $_ } 
     # Otherwise, use the updated line with the new word. 
     else { $line = $next } 
    } 
    } 

    # Return the last line, containing the remainder of the text. 
    $line 
} 

Et voici une autre implémentation pour dedent.

function dedent([string[]]$lines) { 
    # Find the shortest length of leading whitespace common to all lines. 
    $commonLength = (
    $lines | % { 
     $i = 0 
     while($i -lt $_.Length -and [char]::IsWhitespace($_, $i)) { ++$i } 
     $i 
    } | Measure-Object -minimum 
).Minimum 

    # Remove the common whitespace from each string 
    $lines | % { $_.Substring($commonLength) } 
} 

Espérons que leur plus grande verbosité offrira une meilleure clarté :)