PowerShell: stocker tout le contenu du fichier texte dans une variable

118

Je voudrais utiliser PowerShell pour stocker tout le contenu d'un fichier texte (y compris la ligne vierge de fin qui peut exister ou non) dans une variable. J'aimerais également connaître le nombre total de lignes dans le fichier texte. Quelle est la manière la plus efficace d'y parvenir?

pseudo
la source

Réponses:

122

Pour obtenir l'intégralité du contenu d'un fichier:

$content = [IO.File]::ReadAllText(".\test.txt")

Nombre de lignes:

([IO.File]::ReadAllLines(".\test.txt")).length

ou

(gc .\test.ps1).length

Sorte de hackish pour inclure une ligne vide de fin:

[io.file]::ReadAllText(".\desktop\git-python\test.ps1").split("`n").count
manojlds
la source
1
Merci! $content = [IO.File]::ReadAllText(".\test.txt")semble faire la même chose que $content = (gc ".\test.txt" | out-string). Puisque le deuxième des deux est plus court, c'est ce que je préfère. Malheureusement, aucune des méthodes que vous avez fournies pour calculer le nombre total de lignes ne prend en compte les lignes vierges de fin. D'autres idées?
Nick
@Nick In .Net (et windows), toute ligne avec \r\nsera comptée.
manojlds
J'étais en train de faire des expériences et j'ai trouvé la même chose que votre réponse mise à jour, mais je n'y serais pas arrivé sans votre aide, alors merci beaucoup!
Nick
Existe-t-il un moyen de combiner cela de manière transparente avec Invoke-WebRequest?
Kareem
189

Par ailleurs, dans PowerShell 3.0, vous pouvez utiliser l' Get-Contentapplet de commande avec le nouveau commutateur Raw:

$text = Get-Content .\file.txt -Raw 
Shay Levy
la source
3
Cela devrait être la réponse acceptée. À propos, je suis presque sûr que Get-Content fonctionnait même dans les versions antérieures.
MatteoSp
10
@MatteoSp l'a Get-Contentfait, mais ce n'est qu'à partir de la 3.0 qu'il a obtenu -Raw. Sans cela, il est stocké sous forme de tableau de lignes.
jpmc26
Cela devrait absolument être la réponse acceptée. Cela n'aide pas que la documentation indique que le -Rawparamètre n'est implémenté par rien de natif.
Richard Szalay
Merci, c'était une aide précieuse pour le moment.
DAhrens le
24

Powershell 2.0:

(voir l'explication détaillée ici)

$text = Get-Content $filePath | Out-String

Le IO.File.ReadAllTextn'a pas fonctionné pour moi avec un chemin relatif, il recherche le fichier au %USERPROFILE%\$filePathlieu du répertoire actuel (lors de l'exécution à partir de Powershell ISE au moins):

$text = [IO.File]::ReadAllText($filePath)

Powershell 3+:

$text = Get-Content $filePath -Raw
Kapé
la source
Pour utiliser les chemins de parenté, résolvez-le d'abord, par exemple:[IO.File]::ReadAllText((Resolve-Path $filePath))
mvanle
13

Une autre approche de la lecture d'un fichier que j'apprécie est appelée de manière variée notation variable ou syntaxe variable et consiste simplement à enfermer une spécification de fichier entre accolades précédées d'un signe dollar, à savoir:

$content = ${C:file.txt}

Cette notation peut être utilisée comme valeur L ou valeur R ; ainsi, vous pouvez tout aussi facilement écrire dans un fichier avec quelque chose comme ceci:

 ${D:\path\to\file.txt} = $content

Une autre utilisation pratique est que vous pouvez modifier un fichier sur place sans fichier temporaire et sans sous-expressions, par exemple:

${C:file.txt} = ${C:file.txt} | select -skip 1

J'ai d'abord été fasciné par cette notation car il était très difficile d'en savoir plus! Même la spécification PowerShell 2.0 ne le mentionne qu'une seule fois en affichant une seule ligne l'utilisant - mais sans aucune explication ni aucun détail d'utilisation. J'ai par la suite trouvé cette entrée de blog sur les variables PowerShell qui donne de bonnes informations.

Une dernière remarque sur l'utilisation de ceci: vous devez utiliser une désignation de lecteur, c'est- ${drive:filespec}à- dire comme je l'ai fait dans tous les exemples ci-dessus. Sans le lecteur (par exemple ${file.txt}), cela ne fonctionne pas. Aucune restriction sur la spécification de fichier sur ce lecteur: elle peut être absolue ou relative.

Michael Sorens
la source
Je n'ai jamais réussi à faire fonctionner cela à moins de mettre une barre oblique inverse après le nom du lecteur.
Charles Anderson
@CharlesAnderson: On ne sait pas lequel des trois exemples auxquels vous faites référence, ou peut-être tous ... néanmoins, je viens de confirmer que tous les 3 fonctionnent avec un chemin relatif (c'est-à-dire pas de barre oblique inverse) dans PowerShell V3. De plus, au moment de ma réponse, j'utilisais V2, alors peut-être qu'il y a autre chose qui cause un problème dans votre environnement.
Michael Sorens
Je voulais dire des exemples comme $ {C: file.txt}, que je dois écrire comme $ {C: \ file.txt}. Oui, je suppose que cela concerne mon environnement, mais je ne sais pas quoi.
Charles Anderson
Lorsqu'il est utilisé comme valeur L, il utilise le codage par défaut du système. J'ai essayé de définir $ OutputEncoding sans effet. Lorsqu'il est utilisé comme valeur R, il produit un tableau de chaînes [].
robert4
Il semble que vous ne pouvez utiliser qu'un chemin d'accès littéral; vous ne pouvez pas utiliser une variable ou quelque chose comme une expression Join-Path à l'intérieur. Ce qui est ennuyeux, car lorsqu'il est acheminé via ConvertTo-Json, il y a un monde de différence par rapport à Get-Content (et le résultat $ {...} est ce que j'espérais. Je ne sais pas si c'est la même chose comme Get-Content | Out-String cependant
Cameron Kerr
2

Get-Content saisit les données et les vide dans un tableau, ligne par ligne. En supposant qu'il n'y ait pas d'autres exigences spéciales que celles que vous avez énumérées, vous pouvez simplement enregistrer votre contenu dans une variable?

$file = Get-Content c:\file\whatever.txt

L'exécution juste $fileretournera le contenu complet. Ensuite, vous pouvez simplement faire $file.Count(car les tableaux ont déjà une méthode de comptage intégrée) pour obtenir le nombre total de lignes.

J'espère que cela t'aides! Je ne suis pas un sorcier de script, mais cela m'a semblé plus facile que beaucoup de choses ci-dessus.

Jerry T.
la source