PowerShell Set-Content und Out-File - was ist der Unterschied?

85

Was ist in PowerShell der Unterschied zwischen Out-Fileund Set-Content? Oder Add-Contentund Out-File -append?

Ich habe festgestellt, wenn ich beide für dieselbe Datei verwende, ist der Text vollständig mojibaked .

(Eine kleine zweite Frage: >Ist ein Alias ​​für Out-File, oder?)

Oberst Panik
quelle

Antworten:

93

Hier ist eine Zusammenfassung dessen, was ich nach einigen Monaten Erfahrung mit PowerShell und einigen wissenschaftlichen Experimenten abgeleitet habe. Ich habe nichts davon in der Dokumentation gefunden :(

[ Update: Vieles davon scheint jetzt besser dokumentiert zu sein.]

Lese- und Schreibsperre

Während der Out-FileAusführung kann eine andere Anwendung die Protokolldatei lesen.

Während der Set-ContentAusführung können andere Anwendungen die Protokolldatei nicht lesen. So verwenden Sie niemalsSet-Content langen Lauf Befehle zu protokollieren.

Codierung

Out-FileSpeichert standardmäßig in der Unicode( UTF-16LE) - Codierung (obwohl dies angegeben werden kann), während in PowerShell 3+ Set-Contentstandardmäßig ASCII( US-ASCII) verwendet wird (dies kann auch angegeben werden). In früheren PowerShell-Versionen wurden Set-ContentInhalte in der Default(ANSI-) Codierung geschrieben.

Anmerkung der Redaktion : Powershell ab Version 5.1 immer noch standardmäßig auf die kulturspezifische Default( „ANSI“) kodiert, trotz allem , was der Dokumentation Ansprüche. Wenn ASCII die Standardeinstellung wäre, würden Nicht-ASCII-Zeichen üin Literal konvertiert ?, aber das ist nicht der Fall: 'ü' | Set-Content tmp.txt; (Get-Content tmp.txt) -eq '?'Ausbeuten $False.

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

Dies bedeutet, dass die Standardeinstellungen von zwei Befehlen nicht kompatibel sind. Wenn Sie sie mischen, wird der Text beschädigt. Geben Sie daher immer eine Codierung an.

Formatierung

Wie Bartek erklärte, Out-Filespeichert die ausgefallene Formatierung der Ausgabe, wie im Terminal zu sehen. In einem Ordner mit zwei Dateien erstellt der Befehl dir | out-file out.txteine Datei mit 11 Zeilen.

Während Set-Contentspart eine einfachere Darstellung. In diesem Ordner mit zwei Dateien erstellt der Befehl dir | set-content sc.txteine Datei mit zwei Zeilen. So emulieren Sie die Ausgabe im Terminal:

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

Ich glaube, diese Formatierung hat Konsequenzen für Zeilenumbrüche, kann sie aber noch nicht beschreiben.

Dateierstellung

Set-Contenterstellt nicht zuverlässig eine leere Datei, wenn Out-File:

In einem leeren Ordner erstellt der Befehl dir | out-file out.txteine Datei, dies dir | set-content sc.txtjedoch nicht.

Pipeline-Variable

Set-Contentnimmt den Dateinamen aus der Pipeline; So können Sie den Inhalt einer Reihe von Dateien auf einen festen Wert einstellen.

Out-Filenimmt die Daten wie aus der Pipeline; Aktualisieren des Inhalts einer einzelnen Datei.

Parameter

Set-Content enthält die folgenden zusätzlichen Parameter:

  • Ausschließen
  • Filter
  • Einschließen
  • Durchgehen
  • Strom
  • UseTransaction

Out-File enthält die folgenden zusätzlichen Parameter:

  • Anhängen
  • NoClobber
  • Breite

Weitere Informationen zu diesen Parametern finden Sie in der Hilfe. zB get-help out-file -parameter append.

Oberst Panik
quelle
4
Set-ContentStandardcodierung: übersetzt in (Get-Culture).Textinfo.ANSICodePage(Windows 8.1, Powershell 4.0, CurrentCulture cs-CZ, CurrentUICulture en-GB, ANSICodePage 1250, OEMCodePage 852, getestet mit einer 'řž'Zeichenfolge mit verschiedenen Codes auf den obigen Codepages).
JosefZ
Beachten Sie auch, dass Out-Filein bestimmten Situationen Probleme mit langen Schlangen auftreten. Zum Beispiel : $x = [pscustomobject]@{A=('a' * 500); B=('b' * 500)}; $x | Out-File -Path myfile.txt.
Bacon Bits
16

Out-Filehat das Verhalten, den Ausgabepfad zu überschreiben, es sei denn, das -NoClobberund / oder das -AppendFlag ist gesetzt. Add-ContentHängt Inhalte an, wenn der Ausgabepfad bereits standardmäßig vorhanden ist (falls möglich). Beide erstellen die Datei, falls noch keine vorhanden ist.

Ein weiterer interessanter Unterschied besteht darin, dass Add-Contentstandardmäßig eine ASCII-codierte Datei und standardmäßig Out-Fileeine kleine Endian-Unicode-codierte Datei erstellt wird.

>ist ein alias syntaktischer Zucker für Out-File. Es ist Out-Filemit einigen vordefinierten Parametereinstellungen.

Andy Arismendi
quelle
Vielen Dank, dass Sie die Codierungsunterschiede kennen. Du bist nicht ganz richtig, wenn Sie tun echo "" > $null | Add-Content abc.txtes nicht die Datei erstellen abc.txt, während Out-File würde.
Colonel Panic
@ MattHickford Das ist ein seltsames Beispiel für einen Fall. Dieser Code wird an $ null weitergeleitet, Add-Contenterhält also nichts. Wenn Add-Contentnichts empfangen wird, warum sollte es eine Datei erstellen? Auf der anderen Seite könnte die gleiche Frage an Out-File gestellt werden.
Andy Arismendi
Der Unterschied ist für mich wichtig, gci $folder | Out-File log.txt ; cat log.txtwährend er gci $folder | Add-Content log.txt ; cat log.txtexplodiert
Colonel Panic
@MattHickford Ich würde wahrscheinlich sicherstellen, dass die Datei vorhanden ist, bevor ich versuche, sie zu verarbeiten. Wahrscheinlich eine gute Angewohnheit für alle Sprachen.
Andy Arismendi
Ein weiterer Unterschied besteht darin, dass Set-Contentdie Datei während der Verwendung für andere Anwendungen nicht verfügbar ist.
Colonel Panic
10

Nun, ich würde nicht zustimmen ... :)

  1. Out-File hat -Append (-NoClober dient dazu, ein Überschreiben zu vermeiden), das den Inhalt hinzufügt. Aber das ist nicht dasselbe Tier.
  2. Befehl | Add-Content verwendet bei der Eingabe die Methode .ToString (). Out-File verwendet die Standardformatierung.

so:

ls | Add-Content test.txt

und

ls | Out-File test.txt

Sie erhalten völlig unterschiedliche Ergebnisse.

Und nein, '>' ist kein Alias, sondern ein Umleitungsoperator (wie in anderen Shells). Und hat sehr schwerwiegende Einschränkungen ... Es schneidet Linien auf die gleiche Weise, wie sie angezeigt werden. Out-File hat den Parameter -Width, mit dem Sie dies vermeiden können. Außerdem können Sie mit Umleitungsoperatoren nicht entscheiden, welche Codierung verwendet werden soll.

HTH Bartek

BartekB
quelle
3
Es ist ein Alias ​​in der Bedeutung, dass >und Out-File dasselbe sind. Sie nennen den gleichen Code. Aus Bruce Payettes PowerShell in Aktion Zweite Ausgabe (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.
Andy Arismendi
1
Guter Punkt über Standardformatierung (Out-File) vs ToString (Add-Content)
Andy Arismendi
Mein Punkt war: Obwohl beide im Allgemeinen dasselbe tun, hat Alias ​​in PowerShell seine Bedeutung ... daher würde ich diesen Begriff nicht verwenden, um die Beziehung zwischen diesen zu beschreiben ..;) Alias ​​ersetzt Befehl, in diesem Fall sollte es Syntax geben : ls | > file.txt möglich. Offensichtlich wird das nicht funktionieren ...
BartekB
1
Die Standardformatierung ist die Art und Weise, wie ein bestimmtes Objekt in der Konsole dargestellt wird. Die meisten zentralen Cmdlets / Objekttypen verfügen über Formatierungsmetadaten, die PowerShell darüber informieren, wie sie benutzerfreundlich angezeigt werden. Mit anderen Worten: Das Weiterleiten von Befehlsergebnissen an Out-File kann verwendet werden, um die Befehlsausgabe in der Datei zu speichern, ohne die von PowerShell vorgenommene Formatierung zu verlieren.
BartekB
2
Ja, ich denke, es ist eine wichtige Unterscheidung, für die >es nicht genau das Äquivalent gibt out-file. Wenn Sie festlegen $PSDefaultParameterValues["Out-File:Encoding"] = "UTF8", wird es von ignoriert >.
wisbucky
3

Set-Contentunterstützt -Encoding Byte, während Out-Filenicht.

Wenn Sie also Binärdaten oder Ergebnisse von Text.Encoding#GetBytes()in eine Datei schreiben möchten , sollten Sie verwenden Set-Content.

SATO Yusuke
quelle
0

Out-File-Append oder ">>" können tatsächlich zwei Codierungen in derselben Datei mischen. Selbst wenn die Datei ursprünglich ASCII oder Ansi ist, wird standardmäßig Unicode am unteren Rand hinzugefügt. Durch Hinzufügen von Inhalten wird die Codierung überprüft und vor dem Anhängen abgeglichen. Übrigens ist export-csv standardmäßig ascii (keine Akzente) und set-content / add-content auf ansi.

js2010
quelle