PowerShell: archivia l'intero contenuto del file di testo in una variabile


118

Vorrei utilizzare PowerShell per archiviare l' intero contenuto di un file di testo (inclusa la riga vuota finale che può o non può esistere) in una variabile. Vorrei anche conoscere il numero totale di righe nel file di testo. Qual è il modo più efficiente per farlo?

Risposte:


122

Per ottenere l'intero contenuto di un file:

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

Numero di linee:

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

o

(gc .\test.ps1).length

Una sorta di hackish per includere una riga vuota finale:

[io.file]::ReadAllText(".\desktop\git-python\test.ps1").split("`n").count

1
Grazie! $content = [IO.File]::ReadAllText(".\test.txt")sembra fare la stessa cosa di $content = (gc ".\test.txt" | out-string). Dato che il secondo dei due è più corto, è quello che preferisco. Sfortunatamente, nessuno dei metodi forniti per calcolare il numero totale di righe prende in considerazione le righe vuote finali. Altre idee?
Nick

@ Nick In .Net (e Windows), \r\nverrà conteggiata qualsiasi riga con .
manojlds

Stavo facendo alcuni esperimenti e ho trovato la stessa cosa della tua risposta aggiornata, ma non ci sarei arrivata senza il tuo aiuto, quindi grazie mille!
Nick

C'è un modo per combinare in modo trasparente questo con Invoke-WebRequest?
Kareem

189

In una nota a margine, in PowerShell 3.0 è possibile utilizzare il Get-Contentcmdlet con la nuova opzione Raw:

$text = Get-Content .\file.txt -Raw 

3
Questa dovrebbe essere la risposta accettata. A proposito, sono abbastanza sicuro che Get-Content ha funzionato anche nelle versioni precedenti.
MatteoSp

10
@MatteoSp lo ha Get-Contentfatto, ma è stato solo 3.0 che ha ottenuto -Raw. Senza questo, viene memorizzato come un array di linee.
jpmc26

Questa dovrebbe essere assolutamente la risposta accettata. Non aiuta il fatto che la documentazione dica che il -Rawparametro non è implementato da nulla di nativo.
Richard Szalay

Grazie, questo è stato di grande aiuto proprio ora.
DAhrens

24

Powershell 2.0:

(vedi spiegazione dettagliata qui)

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

Il IO.File.ReadAllTextnon ha funzionato per me con un percorso relativo, si cerca il file nella %USERPROFILE%\$filePathanziché la directory corrente (durante l'esecuzione di PowerShell ISE almeno):

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

Powershell 3+:

$text = Get-Content $filePath -Raw

Per utilizzare i percorsi dei parenti, risolverlo prima, ad esempio:[IO.File]::ReadAllText((Resolve-Path $filePath))
mvanle

13

Un altro approccio alla lettura di un file che mi piace è indicato in vari modi come notazione variabile o sintassi variabile e implica semplicemente racchiudere un filespec tra parentesi graffe precedute da un segno di dollaro, vale a dire:

$content = ${C:file.txt}

Questa notazione può essere usata sia come valore L che come valore R ; quindi, potresti scrivere altrettanto facilmente su un file con qualcosa del genere:

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

Un altro utile utilizzo è che puoi modificare un file in posizione senza un file temporaneo e senza sottoespressioni, ad esempio:

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

Inizialmente sono rimasto affascinato da questa notazione perché era molto difficile scoprire qualcosa al riguardo! Anche la specifica PowerShell 2.0 lo menziona solo una volta mostrando solo una riga che lo utilizza, ma senza alcuna spiegazione o dettagli sull'utilizzo. Successivamente ho trovato questa voce di blog sulle variabili di PowerShell che fornisce alcuni buoni approfondimenti.

Un'ultima nota sull'utilizzo di questo: è necessario utilizzare una designazione di unità, cioè ${drive:filespec}come ho fatto in tutti gli esempi precedenti. Senza l'unità (ad esempio ${file.txt}) non funziona. Nessuna restrizione sul filespec su quell'unità: può essere assoluto o relativo.


Non l'ho mai fatto funzionare a meno che non inserissi una barra rovesciata dopo il nome dell'unità.
Charles Anderson

@CharlesAnderson: Non è chiaro a quale dei tre esempi ti riferisci, o forse tutti ... tuttavia, ho appena confermato che tutti e 3 funzionano con un percorso relativo (cioè senza backslash) in PowerShell V3. Inoltre, al momento della risposta stavo usando V2, quindi forse c'è qualcos'altro che causa un problema nel tuo ambiente.
Michael Sorens

Intendevo esempi come $ {C: file.txt}, che devo scrivere come $ {C: \ file.txt}. Sì, presumo sia qualcosa che riguarda il mio ambiente, ma non ho idea di cosa.
Charles Anderson

Quando viene utilizzato come valore L, utilizza la codifica predefinita del sistema. Ho provato a impostare $ OutputEncoding senza alcun effetto. Quando viene utilizzato come valore R, produce un array stringa [].
robert4

Sembra che tu possa usare solo un percorso letterale; non puoi usare una variabile o qualcosa come un'espressione Join-Path all'interno di questo. Il che è fastidioso, perché quando convogliato attraverso ConvertTo-Json, c'è un'enorme differenza rispetto a Get-Content (e il risultato $ {...} è quello che speravo. Non sono sicuro che sia lo stesso come Get-Content | Out-String però
Cameron Kerr

2

Get-Content acquisisce i dati e li scarica in un array, riga per riga. Supponendo che non ci siano altri requisiti speciali rispetto a quelli elencati, potresti semplicemente salvare i tuoi contenuti in una variabile?

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

L'esecuzione $filerestituirà solo l'intero contenuto. Quindi puoi semplicemente fare $file.Count(perché gli array hanno già un metodo di conteggio integrato) per ottenere il numero totale di righe.

Spero che questo ti aiuti! Non sono un mago dello scripting, ma questo mi è sembrato più facile di molte cose sopra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.