PowerShell: Simpan Seluruh Isi File Teks dalam Variabel

118

Saya ingin menggunakan PowerShell untuk menyimpan seluruh konten file teks (termasuk baris kosong yang mungkin ada atau mungkin tidak ada) dalam variabel. Saya juga ingin mengetahui jumlah baris dalam file teks. Apa cara paling efisien untuk melakukan ini?

Nick
sumber

Jawaban:

122

Untuk mendapatkan seluruh konten file:

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

Jumlah baris:

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

atau

(gc .\test.ps1).length

Semacam hackish untuk memasukkan baris kosong trailing:

[io.file]::ReadAllText(".\desktop\git-python\test.ps1").split("`n").count
manojlds
sumber
1
Terima kasih! $content = [IO.File]::ReadAllText(".\test.txt")tampaknya melakukan hal yang sama seperti $content = (gc ".\test.txt" | out-string). Karena yang kedua lebih pendek, itulah yang saya suka. Sayangnya, tidak satu pun dari metode yang Anda berikan untuk menghitung jumlah baris yang mempertimbangkan baris kosong. Ada ide lain?
Nick
@Nick In .Net (dan windows), setiap baris dengan \r\nakan dihitung.
manojlds
Saya sedang melakukan beberapa percobaan dan mendapatkan hal yang sama dengan jawaban terbaru Anda, tetapi saya tidak akan sampai di sana tanpa bantuan Anda, jadi terima kasih banyak!
Nick
Apakah ada cara untuk menggabungkan ini secara transparan Invoke-WebRequest?
Kareem
189

Di samping catatan, di PowerShell 3.0 Anda dapat menggunakan Get-Contentcmdlet dengan sakelar Raw baru:

$text = Get-Content .\file.txt -Raw 
Shay Levy
sumber
3
Ini harus menjadi jawaban yang diterima. Omong-omong, saya cukup yakin Get-Content bekerja bahkan di versi sebelumnya.
MatteoSp
10
@MatteoSp Get-Contentmelakukannya, tetapi tidak sampai 3.0 yang didapat -Raw. Tanpa itu, itu disimpan sebagai array garis.
jpmc26
Ini benar-benar harus menjadi jawaban yang diterima. Itu tidak membantu bahwa dokumentasi mengatakan bahwa -Rawparameter tidak dilaksanakan oleh apa pun asli.
Richard Szalay
Terima kasih, ini sangat membantu sekarang.
DAhrens
24

Powershell 2.0:

(lihat penjelasan rinci di sini)

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

Itu IO.File.ReadAllTexttidak berfungsi untuk saya dengan jalur relatif, itu mencari file %USERPROFILE%\$filePathalih-alih direktori saat ini (saat berjalan dari Powershell ISE setidaknya):

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

Powershell 3+:

$text = Get-Content $filePath -Raw
Kapé
sumber
Untuk menggunakan jalur kerabat, selesaikan dulu misalnya:[IO.File]::ReadAllText((Resolve-Path $filePath))
mvanle
13

Satu lagi pendekatan untuk membaca file yang kebetulan saya suka disebut dengan berbagai cara sebagai notasi variabel atau sintaks variabel dan melibatkan hanya melampirkan filespec dalam tanda kurung kurawal yang didahului dengan tanda dolar, yaitu:

$content = ${C:file.txt}

Notasi ini dapat digunakan sebagai nilai-L atau nilai-R ; dengan demikian, Anda dapat dengan mudah menulis ke file dengan sesuatu seperti ini:

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

Penggunaan praktis lainnya adalah Anda dapat mengubah file di tempat tanpa file sementara dan tanpa sub-ekspresi, misalnya:

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

Saya menjadi terpesona oleh notasi ini pada awalnya karena sangat sulit untuk mencari tahu tentangnya! Bahkan spesifikasi PowerShell 2.0 menyebutkannya hanya sekali yang menunjukkan hanya satu baris yang menggunakannya - tetapi tanpa penjelasan atau detail penggunaan sama sekali. Saya kemudian menemukan entri blog ini tentang variabel PowerShell yang memberikan beberapa wawasan bagus.

Satu catatan terakhir tentang penggunaan ini: Anda harus menggunakan penunjukan drive, yaitu ${drive:filespec}seperti yang telah saya lakukan di semua contoh di atas. Tanpa drive (misalnya ${file.txt}) itu tidak berfungsi. Tidak ada batasan pada filespec di drive itu: mungkin absolut atau relatif.

Michael Sorens
sumber
Saya tidak pernah membuat ini berfungsi kecuali saya meletakkan garis miring terbalik setelah nama drive.
Charles Anderson
@CharlesAnderson: Tidak jelas yang mana dari tiga contoh yang Anda maksud, atau mungkin semuanya ... meskipun demikian, saya baru saja mengonfirmasi bahwa ketiganya bekerja dengan jalur relatif (yaitu tanpa garis miring terbalik) di PowerShell V3. Selanjutnya, pada saat jawaban saya, saya menggunakan V2, jadi mungkin ada hal lain yang menyebabkan masalah di lingkungan Anda.
Michael Sorens
Yang saya maksud adalah contoh seperti $ {C: file.txt}, yang harus saya tulis sebagai $ {C: \ file.txt}. Ya, saya menganggap ini adalah sesuatu tentang lingkungan saya, tetapi saya tidak tahu apa.
Charles Anderson
Saat digunakan sebagai nilai-L, ini menggunakan pengkodean default sistem. Saya mencoba menyetel $ OutputEncoding tanpa efek. Saat digunakan sebagai nilai-R, ini menghasilkan string [] array.
robert4
Tampaknya Anda hanya dapat menggunakan nama jalur literal; Anda tidak dapat menggunakan variabel atau sesuatu seperti ekspresi Join-Path di dalamnya. Yang menjengkelkan, karena ketika disalurkan melalui ConvertTo-Json, ada perbedaan besar dibandingkan dengan Get-Content (dan hasil $ {...} adalah yang saya harapkan. Saya tidak yakin apakah ini sama sebagai Get-Content | Out-String meskipun
Cameron Kerr
2

Get-Content mengambil data dan membuangnya ke dalam array, baris demi baris. Dengan asumsi tidak ada persyaratan khusus selain yang Anda cantumkan, Anda bisa menyimpan konten Anda ke dalam variabel?

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

Menjalankan hanya $fileakan mengembalikan konten lengkap. Maka Anda bisa melakukannya$file.Count (karena array sudah memiliki metode penghitungan bawaan) untuk mendapatkan total # baris.

Semoga ini membantu! Saya bukan ahli scripting, tapi ini tampak lebih mudah bagi saya daripada banyak hal di atas.

Jerry T.
sumber