Pipe compléter tableau-objets au lieu d'éléments de tableau un à la fois?
Comment faites-vous envoyer la sortie d'une Applet de commande à la prochaine dans un pipeline complet de la matrice de l'objet à la place de l'individu éléments du tableau une par une?
Le problème - description Générique
Comme on peut le voir dans l'aide pour about_pipelines (help pipeline
) powershell envoie des objets un à la fois, en bas du pipeline1. Donc Get-Process -Name notepad | Stop-Process
envoie un processus à la fois, en bas du tuyau.
Permet de dire que nous avons un 3ème partie Applet de commande (Do-SomeStuff) qui ne peuvent pas être modifiés en aucune façon. Faire-SomeStuff effectuer différentes si il est passé à un tableau de chaînes ou si il est passé à un seul objet de type string.
Faire-SomeStuff est juste un exemple, il pourrait être remplacé pour ForEach-Object
Select-Object
Write-Host
(ou tout autre Applet de commande d'accepter les entrées de pipeline)
Faire-SomeStuff sera dans cet exemple, le processus de l'individu éléments du tableau un à la fois.
$theArray = @("A", "B", "C")
$theArray | Do-SomeStuff
Si nous voulons envoyer à l'ensemble de la gamme, comme un objet pour le Faire-SomeStuff on pourrait essayer quelque chose comme cela
@($theArray) | Do-SomeStuff
Mais elle ne produit pas le résultat attendu depuis PowerShell "ignore" le nouveau single-point-matrice.
Alors, comment avez-vous "force" $theArray
à être transmis de la pipe comme un seul tableau-objet plutôt que le contenu et les éléments un à la fois?
Le problème - exemple pratique
Comme indiqué ci-dessous, la sortie de Write-Host
est différente en cas d'adoption d'un tableau ou si il a passé les différents éléments dans un tableau à la fois.
PS C:\> $theArray = @("A", "B", "C")
PS C:\> Write-Host $theArray
A B C
PS C:\> $theArray | foreach{Write-Host $_}
A
B
C
PS C:\> @($theArray) | foreach{Write-Host $_}
A
B
C
Comment faites-vous pour obtenir $theArray | foreach{Write-Host $_}
pour produire le même résultat que Write-Host $theArray
?
NOTES de bas de page
- Pipeline de traitement dans Powershell
Normal d'un tableau de chaînes de caractères
PS C:\> @("A", "B", "C").GetType().FullName
System.Object[]
Normal d'un tableau de chaînes de caractères courante à Foreach-Object
PS C:\> @("A", "B", "C") | foreach{$_.GetType().FullName}
System.String
System.String
System.String
Chaque chaîne dans le tableau est traité à la fois par la CmdLet ForEach-Object.
Un tableau de tableaux, où le "intérieure" tableaux sont des tableaux de chaînes de caractères.
PS C:\> @(@("A", "B", "C"), @("D", "E", "F"), @("G", "H", "I")) | foreach{$_.GetType().FullName}
System.Object[]
System.Object[]
System.Object[]
Chaque tableau dans le tableau est traité à la fois par la CmdLet ForEach-Object, et le contenu de chaque sous-tableau à partir de l'entrée est traitée comme un objet, même si c'est un tableau.
source d'informationauteur NoOneSpecial
Vous devez vous connecter pour publier un commentaire.
Réponse courte: utilisation unaire de la matrice de l'opérateur
,
:Réponse longue: il y a une chose que vous devez comprendre au sujet de
@()
opérateur: il est toujours interpréter son contenu, comme déclaration, même si le contenu est juste une expression. Considérer ce code:- Je ajouter explicite fin de l'énoncé de la marque
;
ici, bien que PowerShell permet de le supprimer.$a
est tableau de trois éléments. Quel est le résultat de$a;
déclaration?$a
est une collection, de sorte que la collecte doit être énumérés et chaque élément doit être passé par pipeline. Donc le résultat de$a;
déclaration est de trois éléments écrits dans le pipeline.@($a;)
voir que trois éléments, mais pas le tableau d'origine, et créer une matrice à partir d'eux, de sorte$b
est tableau de trois éléments. Même façon$c
est tableau de trois éléments. Donc, lorsque vous écrivez@($collection)
vous créez une matrice, qui copie les éléments de$collection
au lieu de tableau de simple élément.La virgule met les données dans un tableau. Afin de rendre la conduite du processus de ligne de votre tableau comme un tableau, au lieu d'opérer sur chaque élément du tableau individuellement, vous pouvez aussi avoir besoin d'envelopper les données entre parenthèses.
Ceci est utile si vous avez besoin d'évaluer l'état de plusieurs éléments dans le tableau.
À l'aide de la fonction suivante
Considérons les exemples suivants:
Juste envelopper de votre tableau, entre parenthèses, ne garantit pas la fonction du processus le tableau de valeurs dans un processus d'appel. Dans cet exemple, nous voyons les changements de nombre aléatoire pour chaque élément dans le tableau.
Ajoutant simplement le leader de la virgule, ne garantit pas non plus la fonction de processus le tableau de valeurs dans un processus d'appel. Dans cet exemple, nous voyons les changements de nombre aléatoire pour chaque élément dans le tableau.
Avec les leaders de la virgule et le tableau de valeurs entre parenthèses, on peut voir le nombre aléatoire reste la même puisque la fonction de la commande foreach est utilisée.
Il y a une vieille école de solution, si vous n'avez pas l'esprit que votre processus est une fonction.
Exemple: Vous voulez un tableau copié dans le presse-papiers dans une manière qui vous permet de le construire à nouveau sur un autre système, sans aucune PSRemoting de connectivité. Donc, vous voulez un tableau contenant "A", "B" et "C" pour le transmuter en une chaîne:
@("A","B","C")
...au lieu d'un littéral de tableau.
Afin que vous puissiez construire ce qui n'est pas optimal pour d'autres raisons, mais rester sur le sujet):
et il fonctionne lorsque vous spécifiez le tableau comme paramètre directement:
Sérialiser-Liste $liste
@("A","B","C")
...mais pas tellement quand vous passez à travers le pipeline:
$liste | Sérialiser-Liste
@("C")
Mais refactoriser le code de votre fonction avec commencer, processus, et en fin de bloc:
...et vous obtenez le résultat souhaité de deux manières.
Sérialiser-Liste $liste
@("A","B","C")
$liste | Sérialiser-Liste
@("A","B","C")