PowerShell Set-Content та Out-File - у чому різниця?


Відповіді:


95

Ось короткий виклад того, що я вивів після кількох місяців досвіду роботи з PowerShell та деяких наукових експериментів. Я нічого з цього не знайшов у документації :(

[ Оновлення: Багато з цього зараз, мабуть, краще задокументовано.]

Блокування читання та запису

Під час Out-Fileроботи інша програма може читати файл журналу.

Під час Set-Contentроботи інші програми не можуть прочитати файл журналу. Тому ніколи не використовуйтеSet-Content для реєстрації тривалих команд.

Кодування

Out-Fileзберігає в кодуванні Unicode( UTF-16LE) за замовчуванням (хоча це можна вказати), тоді як Set-Contentза замовчуванням ASCII( US-ASCII) у PowerShell 3+ (це також може бути вказано). У попередніх версіях PowerShell Set-Contentписав вміст у Defaultкодуванні (ANSI).

Примітка редактора : PowerShell, починаючи з версії 5.1, як і раніше за замовчуванням використовує специфічне для культури Defaultкодування ("ANSI"), незважаючи на те, що заявляється в документації. Якби ASCII був за замовчуванням, символи, що не належать до ASCII, такі як üби були перетворені в літерал ? , але це не так: 'ü' | Set-Content tmp.txt; (Get-Content tmp.txt) -eq '?'yields $False.

PS > $null | out-file outed.txt
PS > $null | set-content set.txt
PS > md5sum *
f3b25701fe362ec84616a93a45ce9998 *outed.txt
d41d8cd98f00b204e9800998ecf8427e *set.txt

Це означає, що за замовчуванням дві команди несумісні, і їх змішування призведе до пошкодження тексту, тому завжди вказуйте кодування.

Форматування

Як пояснив Бартек, Out-Fileзберігається вигадливе форматування виводу, як це видно на терміналі. Отже, у папці з двома файлами команда dir | out-file out.txtстворює файл із 11 рядками.

Тоді як Set-Contentзберігається більш просте представлення. У цій папці з двома файлами команда dir | set-content sc.txtстворює файл із двома рядками. Для емуляції виводу в терміналі:

PS > dir | ForEach-Object {$_.ToString()}
out.txt
sc.txt

Я вважаю, що це форматування має наслідком для розривів рядків, але я поки не можу описати це.

Створення файлу

Set-Contentне надійно створює порожній файл, коли Out-File:

У порожній папці команда dir | out-file out.txtстворює файл, тоді як dir | set-content sc.txtні.

Змінна трубопроводу

Set-Contentбере ім'я файлу з конвеєра; що дозволяє встановити кількість вмісту файлів на деяке фіксоване значення.

Out-Fileприймає дані з конвеєру; оновлення вмісту одного файлу.

Параметри

Set-Content включає наступні додаткові параметри:

  • Виключити
  • Фільтр
  • Включати
  • PassThru
  • Потік
  • UseTransaction

Out-File включає наступні додаткові параметри:

  • Додайте
  • NoClobber
  • Ширина

Для отримання додаткової інформації про те, що це за параметри, зверніться до довідки; напр get-help out-file -parameter append.


4
Set-Contentкодування за замовчуванням: переведено у (Get-Culture).Textinfo.ANSICodePage(Windows 8.1, Powershell 4.0, CurrentCulture cs-CZ, CurrentUICulture en-GB, ANSICodePage 1250, OEMCodePage 852, протестовано із використанням 'řž'рядка з різними кодами на наведених вище кодових сторінках).
JosefZ

Також зверніть увагу, що Out-Fileв певних ситуаціях виникають проблеми із довгими чергами. Наприклад: $x = [pscustomobject]@{A=('a' * 500); B=('b' * 500)}; $x | Out-File -Path myfile.txt.
Bacon Bits

17

Out-Fileмає поведінку перезапису вихідного шляху, якщо не встановлено -NoClobberі / або -Appendпрапор. Add-Contentдодасть вміст, якщо вихідний шлях уже існує за замовчуванням (якщо він може). Обидва створять файл, якщо він ще не існує.

Інша цікава відмінність полягає в тому, що Add-Contentза замовчуванням Out-Fileбуде створений файл, кодований ASCII, і за замовчуванням створить невеликий кодований файл Unicod Unicode.

>є псевдонімом синтаксичного цукру для Out-File. Це Out-Fileз деякими заздалегідь заданими параметрами параметрів.


Дякую, знання відмінностей у кодуванні корисно. Ви не зовсім праві, якщо це зробите, echo "" > $null | Add-Content abc.txtце не створить файл abc.txt, тоді як Out-File це зробить.
Полковник Панік

@MattHickford Це якось дивний приклад. Цей код передає $ null, тому Add-Contentне отримує нічого. Якщо Add-Contentнічого не отримує, навіщо створювати файл? З іншого боку, те саме питання можна було б поставити і поза архівами.
Енді Арісменді,

Різниця, яка для мене має значення, gci $folder | Out-File log.txt ; cat log.txtпрацює, тоді як gci $folder | Add-Content log.txt ; cat log.txtпідривається
полковник Паніка,

@MattHickford Я б, мабуть, переконався, що файл існує, перш ніж намагатися його обробити. Можливо, це гарна звичка для всіх мов.
Енді Арісменді,

Інша відмінність полягає в тому, що під Set-Contentчас використання файл недоступний для інших програм.
Colonel Panic

10

Ну, я б не погодився ... :)

  1. Out-File має -Append (-NoClober існує, щоб уникнути перезапису), що буде Add-Content. Але це не той самий звір.
  2. команда | Add-Content використовуватиме метод .ToString () при введенні. Out-File використовуватиме форматування за замовчуванням.

тому:

ls | Add-Content test.txt

і

ls | Out-File test.txt

дасть вам абсолютно різні результати.

І ні, '>' - це не псевдонім, це оператор перенаправлення (такий самий, як і в інших оболонках). І має дуже серйозне обмеження ... Це буде вирізати лінії так само, як вони відображаються. Out-File має параметр -Width, який допомагає вам цього уникнути. Крім того, за допомогою операторів переспрямування ви не можете вирішити, яке кодування використовувати.

HTH Бартек


3
Це псевдонім у значенні, що >і Out-File - це одне і те ж. Вони називають один і той же код. З другого видання PowerShell в дії Брюса Пайєта (Kindle Locations 4646):In fact, myScript > file.txt is just “syntactic sugar” for myScript | out-file -path file.txt In some cases, you’ll want to use Out-File directly because it gives you more control over the way the output is written.
Енді Арісменді,

1
Хороший момент щодо форматування за замовчуванням (Out-File) проти ToString (Add-Content)
Енді Арісменді,

Моя думка полягала в тому, що, хоча обидва вони взагалі однакові, псевдонім має це значення в PowerShell ... тому я б не використовував цей термін для опису відносин між ними ..;) Псевдонім замінює команду, в цьому випадку він повинен робити синтаксис : ls | > file.txt можливо. Очевидно, це не спрацює ...
BartekB

1
Форматування за замовчуванням - це спосіб представлення даного об’єкта в консолі. Більшість основних командлетів / типів об’єктів мають метадані форматування, які інформують PowerShell про те, як відображати їх зручним для користувача способом. Іншими словами: передача результатів команди до Out-File може бути використана для збереження виводу команди у файл, не втрачаючи форматування, виконане PowerShell.
BartekB

2
Так, я думаю, що це важлива відмінність, яка >не є точним еквівалентом out-file. Якщо встановити $PSDefaultParameterValues["Out-File:Encoding"] = "UTF8", він буде проігнорований >.
Wisbucky

3

Set-Contentпідтримує -Encoding Byte, тоді як Out-Fileні.

Отже, коли ви хочете записати двійкові дані або результат у Text.Encoding#GetBytes()файл, вам слід використовувати Set-Content.


0

Out-file -append або ">>" насправді може змішувати два кодування в одному файлі. Навіть якщо файл спочатку є ascii або ansi, він за замовчуванням додасть Unicode внизу. Add-content перевірить кодування та зрівняє його перед додаванням. До речі, за замовчуванням export-csv має значення ascii (без акцентів), а set-content / add-content - ansi.

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