1
votes

Est-il possible de définir une variable Powershell sur N caractères fixes?

Je me demande s'il est possible de définir une variable dans Powershell à N nombre de caractères.

Exemple n ° 1

Je veux que la variable $ Name soit toujours fixée à 5 caractères. Donc si je suis où écrire:

$ Name = 'Alex'

Le résultat que j'attends serait: 'Alex'

Alex contient 4 caractères donc la variable comprendrait et ajouterait les caractères d'espace nécessaires.

Exemple n ° 2

$ Name = 'A'

Résultat: 'A'

'A' est un caractère et donc la variable doit ajouter 4 espaces.

Existe-t-il un moyen de définir cette règle pour la variable $ Name ?


7 commentaires

Que se passe-t-il si vous définissez $ Name = "MoreThanFiveCharacters" ?


Réponse courte: non, sauf si vous avez cherché des types personnalisés qui effectuent cette validation et ont une conversion de / vers string , ce qui est presque certainement plus problématique que cela ne vaut la peine (lire: vous voulez un "bon" langage de programmation pour cela et non PowerShell).


cela vous permettra de remplir une valeur avec des espaces >>> ('{0,4}' -f 'a') <<< le résultat est `a`. [ sourire ]


@ MathiasR.Jessen J'utilise la validation de longueur de chaîne pour cela, il y a une excellente discussion à ce sujet dans la pile: stackoverflow.com/questions/46421158/...


@JeroenMostert Salut, je suis d'accord avec vous mais je suis dans une position où je dois le faire en PowerShell. Quelque chose comme: while ($ Name.Length -lt 30) {$ Space = ''; $ Nom + = $ Espace}


Vous pouvez effectuer une validation / un remplissage de chaîne dans PowerShell via des fonctions; ce n'est pas le problème. Le problème est de l'incorporer dans une variable de telle manière qu'elle n'échoue jamais ou qu'elle revienne à une ancienne chaîne , quel que soit le cas d'utilisation; cela représente plus de problèmes que cela ne vaut la peine. Il est préférable de définir et de vérifier de telles choses aux bords de vos couches d'entrée / sortie et d'utiliser une ancienne chaîne à l'intérieur des scripts eux-mêmes.


Pourquoi voudriez-vous avoir une chaîne de longueur fixe de toute façon? Veuillez décrire le cas d'utilisation, peut-être qu'il existe des solutions prêtes à l'emploi.


3 Réponses :


0
votes

Cela devrait faire ce que vous voulez:

function Set-FixedVariable {

    param( [parameter(mandatory)][string]$name,
           [parameter(mandatory)][string]$value,
           [parameter(mandatory)][int]$size
    )

    $sb = [System.Text.Stringbuilder]::new( ' ' * $size )
    [void]$sb.Insert(0, $value)

    Set-Variable -Name $name -Value $sb.ToString().Substring(0, $size) -Scope Script -Force

    return $value

}


Set-FixedVariable -name 'ab' -value 'Alex' -size 10

$ab.Length


5 commentaires

Cela ne suffirait-il pas? while ($ Name.Length -lt 30) {$ Space = ''; $ Name + = $ Space} déformer ceci dans une fonction et le rendre réutilisable?


Cela n'empêche pas de modifier $ ab . L'exécution de $ ab = "bob"; $ ab.length renvoie 3.


Mis à part le point valide de @vonPryz, votre fonction ne fonctionnera comme prévu que lorsqu'elle sera appelée directement depuis la portée script . Sinon, vous allez modifier une variable différente, notamment lorsqu'elle est appelée depuis une autre fonction avec une variable locale de fonction ou lorsque vous incluez cette fonction dans un module et l'appelez de l'extérieur. Enfin, bien que ce ne soit qu'un petit problème: une commande Set- ne devrait rien renvoyer, sauf si -PassThru est également spécifié. Le fait que la fonction renvoie actuellement la valeur originale , non ajoutée, ajoute à la confusion.


Cela a été pensé comme une aide brève pour le demandeur, pas comme un modèle pour un module global prenant en compte chaque circonstance.


Veuillez ensuite indiquer clairement les limites de votre solution en préambule dans votre réponse. Les réponses ne sont jamais juste pour le demandeur; de nombreux lecteurs viendront ici au fil du temps, avec des exigences (légèrement) différentes, il est donc important de leur parler des hypothèses, des limites et des raccourcis pris. En dehors de cela, votre réponse ne mentionne même pas actuellement que votre solution ne satisfait pas l'exigence expresse du demandeur d'appliquer également le remplissage lors de l'affectation .



3
votes

Dans PowerShell 5.1 et versions ultérieures, vous pouvez créer un ArgumentTransformationAttribute sous-classe:

[StringLengthTransformation()]$Name = 'Alex'
# $Name is now 'Alex '

$Name = 'Alexandra'
# $Name is now 'Alexa'

[StringLengthTransformation(10, '-')]$Name = 'Alex'
# $Name is now 'Alex------'

Maintenant, lorsqu'elle est appliquée à une variable, elle transformera tout ce que vous lui attribuez:

using namespace System.Management.Automation

class StringLengthTransformationAttribute : ArgumentTransformationAttribute
{
    [ValidateRange(0,1024)]
    [int]$Length = 5

    [char]$PaddingChar = ' '

    StringLengthTransformationAttribute()
    {
    }

    StringLengthTransformationAttribute([int]$Length)
    {
        $this.Length = $Length
    }

    StringLengthTransformationAttribute([int]$Length, [char]$PaddingChar)
    {
        $this.Length = $Length
        $this.PaddingChar = $PaddingChar
    }

    [object]
    Transform([EngineIntrinsics]$engineIntrinsics, [object]$inputData)
    {
        return $inputData -replace "^(.{$($this.Length)}).*$",'$1' |% PadRight $this.Length $this.PaddingChar
    }
}


0 commentaires

0
votes

En regardant les réponses, j'ai l'impression que les gens rendent cela trop difficile, la longueur devrait être suffisante.

function Add-Spaces
{
Param (
    [string]$Name
)

do
{
    $name.length
    $name += ' '
}
while ($name.Length -ne '5')
}

$name = 'Bas'

Add-Spaces -Name $name


1 commentaires

Cela ne satisfait aucune des exigences d'origine (contraindre une chaîne variable à un nombre fixe de caractères, avec un espace pour les valeurs plus courtes). Votre fonction ne renvoie même pas une valeur complétée, elle retourne un tableau de longueurs de chaîne (en sortie implicitement et vraisemblablement accidentellement $ name.Length ). La fonctionnalité prévue peut être obtenue sans fonction, en appelant simplement $ name.PadRight (5, '') , mais cela ne répond toujours pas au désir d'appliquer le length, et, plus important encore, que la restriction de longueur et le remplissage doivent être appliqués lors de l ' attribution à $ name .