PowerShell: Зберігайте весь вміст текстового файлу в змінному


118

Я хотів би використовувати PowerShell для зберігання всього вмісту текстового файлу (включаючи пробіл, який може бути, а може і не існувати) у змінній. Я також хотів би знати загальну кількість рядків у текстовому файлі. Який найефективніший спосіб це зробити?

Відповіді:


122

Щоб отримати весь вміст файлу:

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

Кількість рядків:

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

або

(gc .\test.ps1).length

Сорт хакіша, щоб включити останню пусту рядок:

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

1
Дякую! $content = [IO.File]::ReadAllText(".\test.txt")здається, робить те саме, що і $content = (gc ".\test.txt" | out-string). Оскільки другий з двох коротший, саме тому я віддаю перевагу. На жаль, жоден із методів, які ви надали для обчислення загальної кількості рядків, не враховує проміжні порожні рядки. Будь-які інші ідеї?
Нік

@Nick In .Net (і вікна), будь-який рядок з \r\nбуде враховано.
manojlds

Я робив кілька експериментів і придумав те саме, що і ваша оновлена ​​відповідь, але я не потрапив би без вашої допомоги, тому дуже дякую!
Нік

Чи є спосіб прозоро поєднати це Invoke-WebRequest?
Карім

189

З іншого боку, в PowerShell 3.0 ви можете використовувати Get-Contentкомандлет з новим перемикачем Raw:

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

3
Це має бути прийнятою відповіддю. До речі, я впевнений, що Get-Content працював навіть у попередніх версіях.
MatteoSp

10
@MatteoSp так і Get-Contentзробив, але це було не тільки до 3.0 -Raw. Без цього він зберігається як масив рядків.
jpmc26

Це абсолютно має бути прийнятою відповіддю. Це не допомагає, що в документації йдеться про те, що -Rawпараметр не реалізований жодним нативним.
Річард Шалай

Дякую, це була чудова допомога саме зараз.
DAhrens

24

Powershell 2.0:

(докладні пояснення див. тут)

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

У IO.File.ReadAllTextмене не було відносного шляху, він шукає файл %USERPROFILE%\$filePathзамість поточного каталогу (при запуску з Powershell ISE принаймні):

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

Powershell 3+:

$text = Get-Content $filePath -Raw

Щоб скористатися [IO.File]::ReadAllText((Resolve-Path $filePath))
родичевими

13

Ще один підхід до читання файлу, який мені подобається, називається по-різному як нотація змінної або синтаксис змінної і включає просто закриття filepec у фігурні дужки, що передують знаку долара:

$content = ${C:file.txt}

Ця позначення може використовуватися як значення L, або R ; таким чином, ви можете так само легко записати у файл щось подібне:

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

Ще одне зручне використання полягає в тому, що ви можете змінювати файл на місці без тимчасового файлу і без підвиразів, наприклад:

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

Я спочатку захопився цим позначенням, бо про це було дуже важко дізнатися! Навіть специфікація PowerShell 2.0 згадує про це лише один раз, показуючи лише один рядок, використовуючи його, але без пояснень та деталей використання. Згодом я знайшов цю запис у блозі про змінні PowerShell, яка дає хороші уявлення.

Останнє зауваження щодо використання цього: ви повинні використовувати позначення приводу, тобто ${drive:filespec}як я це зробив у всіх прикладах вище. Без приводу (наприклад ${file.txt}) це не працює. На цьому диску немає обмежень на filepec: він може бути абсолютним або відносним.


Я ніколи цього не спрацьовував, якщо не поставив зворотну косу рису після імені диска.
Чарльз Андерсон

@CharlesAnderson: Незрозуміло, про який із трьох прикладів ви посилаєтесь, чи, можливо, всі вони ... тим не менше, я просто підтвердив, що всі 3 працюють з відносним шляхом (тобто відсутністю зворотної косої риси) в PowerShell V3. Далі, під час моєї відповіді я використовував V2, тому, можливо, щось інше спричиняє проблему у вашому оточенні.
Майкл Соренс

Я мав на увазі такі приклади, як $ {C: file.txt}, які я повинен писати як $ {C: \ file.txt}. Так, я припускаю, що це щось стосується мого оточення, але я поняття не маю.
Чарльз Андерсон

Використовуючи як L-значення, воно використовує кодування за замовчуванням системи. Я намагався встановити $ OutputEncoding без ефекту. Використовуючи як R-значення, він створює масив string [].
robert4

Здається, ви можете використовувати лише буквальне ім'я шляху; ви не можете використовувати змінну чи щось подібне до виразу Join-Path. Що дратує, тому що, переходячи через ConvertTo-Json, існує світ різниці порівняно з Get-Content (і результат, на який я сподівався $ {...}. Я не впевнений, чи це те саме як Get-Content | Вихідні струни, проте
Камерон Керр

2

Get-Content захоплює дані та скидає їх у масив, рядок за рядком. Якщо припустити, що немає інших спеціальних вимог, ніж ви перераховані, ви можете просто зберегти свій вміст у змінній?

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

Запуск лише $fileповерне повний вміст. Тоді можна просто зробити$file.Count (оскільки масиви вже мають вбудований метод підрахунку), щоб отримати загальну кількість # рядків.

Сподіваюся, це допомагає! Я не майстер сценаріїв, але мені це здалося легшим, ніж багато речей вище.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.