Si j'ai un fichier texte, C:\USER\Documents\Collections\collection.txt qui contient les informations suivantes:
collectionA.json
collectionB.json
collectionC.json
collectionD.json
Je me demande comment, via Powershell, je suis capable de stocker chaque ligne dans le fichier texte en tant qu'éléments d'un tableau tel que ..
array arrayFromFile = new Array;
foreach(line x in collection.txt)
{
arrayFromFile.Add(x);
}
..avec l'objectif final de faire ce qui suit:
foreach(string x in arrayFromFile)
{
newman run x;
}
Mes excuses pour la question apparemment facile - je n'ai jamais eu affaire à Powershell auparavant.
La commande Get-Content
Renvoie chaque ligne d'un fichier texte sous forme de chaîne distincte, vous donnera donc un tableau (tant que vous n'utilisez pas le paramètre -Raw
; Ce qui fait que toutes les lignes sont combiné à une seule chaîne).
[string[]]$arrayFromFile = Get-Content -Path 'C:\USER\Documents\Collections\collection.txt'
Dans son excellente réponse , mklement0 donne beaucoup plus de détails sur ce qui se passe réellement lorsque vous appelez cette commande, ainsi que des approches alternatives si vous vous souciez des performances plutôt que de la commodité. Vaut vraiment la peine d'être lu si vous souhaitez en savoir plus sur la langue plutôt que de simplement résoudre cette exigence unique.
Pour compléter réponse utile de JohnLBevan :
Get-Content
, en tant qu'applet de commande , génère les objets un par un au pipeline , à mesure qu'ils deviennent disponibles . (Notez qu'un pipeline est impliqué lors de l'appel d'une applet de commande même en l'absence du symbole de canal, |
, Pour chaîner plusieurs commandes ).
Dans ce cas, les objets de sortie sont les lignes individuelles du fichier texte d'entrée.
Si vous collectez les objets de sortie d'un pipeline , comme par l'assigner à une variable telle que $arrayFromFile
ou en utilisant le pipeline dans le contexte d'une expression plus grande avec (...)
:
[object[]]
,Afin de s'assurer que la sortie d'un pipeline est toujours un tableau, PowerShell propose @(...)
, le tableau -subexpression operator, qui enveloppe même la sortie d'un seul objet dans un tableau.
Par conséquent, la solution PowerShell-idiomatique est:
$arrayFromFile = @(Get-Content C:\USER\Documents\Collections\collection.txt)
Cependant, il n'est souvent pas nécessaire de s'assurer que vous recevez toujours un tableau , car PowerShell traite les scalaires (valeurs uniques qui ne sont pas des collections) comme les tableaux (collections) dans de nombreux contextes, comme dans les instructions foreach
ou lors de la sortie d'une valeur à énumérer dans le pipeline.
TheMadTechnician souligne que vous pouvez également utiliser [Array]
Pour convertir/taper la sortie du pipeline comme alternative à @(...)
, qui crée également des tableaux [object[]]
:
# Equivalent of the command above that additionally locks in the variable date type.
[Array] $arrayFromFile = Get-Content C:\USER\Documents\Collections\collection.txt
En utilisant [Array] $arrayFromFile = ...
Plutôt que $arrayFromFile = [Array] (...)
, la variable $arrayFromFile
Devient contrainte de type , ce qui signifie que son type de données est verrouillé dans (alors que par défaut PowerShell vous permet de changer le type d'une variable à tout moment).
[Array]
Est une alternative indépendante de la commande à la distribution spécifique au type utilisée dans la réponse de John, [string[]]
; vous pouvez utiliser ce dernier pour imposer l'utilisation d'un type uniforme sur les éléments du tableau, mais cela n'est souvent pas nécessaire dans PowerShell[1] .
Les tableaux PowerShell standard sont de type [object[]]
, Ce qui permet de mélanger des éléments de différents types, mais tout élément donné a toujours un type spécifique; Par exemple, même si le type de $arrayFromFile
après la commande ci-dessus est [object[]]
, le type de $arrayFromFile[0]
, c'est-à-dire le 1er élément, par exemple, est [string]
(en supposant que le fichier contenait au moins 1 ligne; vérifiez le type avec $arrayFromFile[0].GetType().Name
).
Les applets de commande et le pipeline offrent des fonctionnalités de haut niveau potentiellement réductrices de mémoire qui sont expressives et pratiques, mais elles peuvent être lentes .
Lorsque les performances sont importantes, une utilisation directe des types de framework .NET est nécessaire, comme [System.IO.File]
dans ce cas.
$arrayFromFile = [IO.File]::ReadAllLines('C:\USER\Documents\Collections\collection.txt')
Notez comment le préfixe System.
Peut être omis du nom du type.
Comme dans la réponse de John, cela retournera un tableau [string[]]
.
Mises en garde :
Soyez prudent avec les chemins relatifs , car .NET a généralement un répertoire courant différent que PowerShell; pour contourner ce problème, passez toujours des chemins absolus , par ex. avec "$PWD/collection.txt"
.
. L'encodage par défaut de NET est UTF-8, tandis que Windows PowerShell utilise par défaut l'encodage "ANSI" , c'est-à-dire la page de code héritée des paramètres régionaux du système; PowerShell Core , en revanche, utilise également par défaut UTF-8. Utilisez le paramètre Get-Encoding
De -Encoding
Ou la surcharge .ReadAllLines()
qui accepte une instance d'encodage pour spécifier explicitement l'encodage des caractères du fichier d'entrée.
[1] Généralement, les conversions implicites de type d'exécution de PowerShell ne peuvent pas fournir le même type de sécurité que vous obtiendriez en C #, par exemple. Par exemple, [string[]] $a = 'one', 'two'; $a[0] = 42
Ne provoque pas une erreur: PowerShell convertit simplement silencieusement [int]
42
En une chaîne.
$array = Get-Content -Path @("C:\tmp\sample.txt")
foreach($item in $array)
{
write-Host $item
}