PowerShell Set-Content dan Out-File - apa bedanya?

90

Di PowerShell, apa perbedaan antara Out-Filedan Set-Content? Atau Add-Contentdan Out-File -append?

Saya telah menemukan jika saya menggunakan keduanya pada file yang sama, teksnya sepenuhnya mojibaked .

(Pertanyaan kecil kedua: >apakah alias untuk Out-File, kan?)

Kolonel Panik
sumber

Jawaban:

96

Berikut ringkasan dari apa yang telah saya simpulkan, setelah pengalaman beberapa bulan dengan PowerShell, dan beberapa eksperimen ilmiah. Saya tidak pernah menemukan semua ini di dokumentasi :(

[ Pembaruan: Banyak dari ini sekarang tampaknya didokumentasikan dengan lebih baik.]

Membaca dan menulis penguncian

Saat Out-Filesedang berjalan, aplikasi lain dapat membaca file log.

Saat Set-Contentberjalan, aplikasi lain tidak dapat membaca file log. Jadi jangan pernah gunakanSet-Content untuk mencatat perintah yang berjalan lama.

Pengkodean

Out-Filemenyimpan dalam pengkodean Unicode( UTF-16LE) secara default (meskipun ini dapat ditentukan), sedangkan Set-Contentdefault ke ASCII( US-ASCII) dalam PowerShell 3+ (ini juga dapat ditentukan). Di versi PowerShell sebelumnya, Set-Contentmenulis konten dalam Defaultpengkodean (ANSI).

Catatan editor : PowerShell pada versi 5.1 masih secara default menggunakan Defaultpengkodean khusus budaya ("ANSI"), terlepas dari apa yang diklaim oleh dokumentasi. Jika ASCII adalah default, karakter non-ASCII seperti üakan dikonversi ke literal ? , tetapi tidak demikian: 'ü' | Set-Content tmp.txt; (Get-Content tmp.txt) -eq '?'hasil $False.

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

Ini berarti default dua perintah tidak kompatibel, dan mencampurkannya akan merusak teks, jadi selalu tentukan encoding.

Pemformatan

Seperti yang dijelaskan Bartek, Out-Filemenyimpan format keluaran yang mewah, seperti yang terlihat di terminal. Jadi dalam folder dengan dua file, perintah dir | out-file out.txtmembuat file dengan 11 baris.

Padahal Set-Contentmenyimpan representasi yang lebih sederhana. Di folder dengan dua file itu, perintah dir | set-content sc.txtmembuat file dengan dua baris. Untuk mengemulasi output di terminal:

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

Saya yakin pemformatan ini memiliki konsekuensi untuk jeda baris, tetapi saya belum bisa menjelaskannya.

Pembuatan file

Set-Contenttidak andal membuat file kosong ketika Out-File:

Dalam folder kosong, perintah dir | out-file out.txtmembuat file, sedangkan dir | set-content sc.txttidak.

Variabel Pipa

Set-Contentmengambil nama file dari pipa; memungkinkan Anda untuk mengatur sejumlah konten file ke beberapa nilai tetap.

Out-Filemengambil data dari pipeline; memperbarui konten satu file.

Parameter

Set-Content termasuk parameter tambahan berikut:

  • Mengecualikan
  • Saring
  • Sertakan
  • PassThru
  • Aliran
  • UseTransaction

Out-File termasuk parameter tambahan berikut:

  • Menambahkan
  • NoClobber
  • Lebar

Untuk informasi lebih lanjut tentang apa saja parameter tersebut, silakan merujuk ke bantuan; mis get-help out-file -parameter append.

Kolonel Panik
sumber
4
Set-Contentpengkodean default: diterjemahkan ke (Get-Culture).Textinfo.ANSICodePage(Windows 8.1, Powershell 4.0, CurrentCulture cs-CZ, CurrentUICulture en-GB, ANSICodePage 1250, OEMCodePage 852, diuji menggunakan 'řž'string dengan kode berbeda di halaman kode di atas).
JosefZ
Perhatikan juga bahwa Out-Filememiliki masalah dengan antrean panjang dalam situasi tertentu. Sebagai contoh: $x = [pscustomobject]@{A=('a' * 500); B=('b' * 500)}; $x | Out-File -Path myfile.txt.
Bacon Bits
17

Out-Filememiliki perilaku menimpa jalur keluaran kecuali jika -NoClobberdan / atau -Appendtanda disetel. Add-Contentakan menambahkan konten jika jalur keluaran sudah ada secara default (jika bisa). Keduanya akan membuat file jika belum ada.

Perbedaan menarik lainnya adalah bahwa Add-Contentakan membuat file yang dikodekan ASCII secara default dan Out-Fileakan membuat file enkode unicode endian kecil secara default.

>adalah alias gula sintaksis untuk Out-File. Ini Out-Filedengan beberapa pengaturan parameter yang telah ditentukan sebelumnya.

Andy Arismendi
sumber
Terima kasih, mengetahui perbedaan pengkodean itu berguna. Anda tidak benar, jika Anda melakukannya echo "" > $null | Add-Content abc.txtitu tidak membuat file abc.txt, sedangkan Out-File akan.
Kolonel Panic
@MattHickford Itu contoh kasus tepi yang aneh. Kode itu disalurkan ke $ null sehingga Add-Contenttidak menerima apa pun. Jika Add-Contenttidak menerima apa-apa mengapa harus membuat file? Di sisi lain, pertanyaan yang sama dapat ditanyakan tentang Out-File.
Andy Arismendi
Perbedaan yang penting bagi saya gci $folder | Out-File log.txt ; cat log.txtbekerja saat gci $folder | Add-Content log.txt ; cat log.txtmeledak
Kolonel Panic
@MattHickford Saya mungkin akan memastikan file tersebut ada sebelum mencoba memprosesnya. Mungkin kebiasaan yang baik untuk semua bahasa.
Andy Arismendi
Perbedaan lainnya adalah ketika Set-Contentsedang digunakan, file tersebut tidak tersedia untuk aplikasi lain.
Kolonel Panic
10

Yah, saya tidak setuju ... :)

  1. Out-File memiliki -Append (-NoClober ada untuk menghindari penimpaan) yang akan menambahkan-Konten. Tapi ini bukan binatang yang sama.
  2. perintah | Add-Content akan menggunakan metode .ToString () pada input. Out-File akan menggunakan format default.

begitu:

ls | Add-Content test.txt

dan

ls | Out-File test.txt

akan memberi Anda hasil yang sangat berbeda.

Dan tidak, '>' bukanlah alias, itu operator pengalihan (sama seperti di shell lain). Dan memiliki batasan yang sangat serius ... Ini akan memotong garis seperti yang ditampilkan. Out-File memiliki parameter -Width yang membantu Anda menghindari hal ini. Selain itu, dengan operator pengalihan, Anda tidak dapat memutuskan pengkodean apa yang akan digunakan.

HTH Bartek

BartekB
sumber
3
Ini adalah alias dalam arti bahwa >dan Out-File adalah hal yang sama. Mereka menyebut kode yang sama. Dari Bruce Payette's PowerShell in Action Edisi Kedua (Lokasi Kindle 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
Poin bagus tentang pemformatan default (File Keluar) vs ToString (Tambah-Konten)
Andy Arismendi
Maksud saya adalah: meskipun keduanya secara umum sama, alias memiliki arti di PowerShell ... jadi saya tidak akan menggunakan istilah ini untuk menggambarkan hubungan antara mereka juga ..;) Alias ​​menggantikan perintah, dalam hal ini harus membuat sintaks : ls | > file.txt mungkin. Jelas, itu tidak akan berhasil ...
BartekB
1
Pemformatan default adalah cara objek yang diberikan disajikan di konsol. Sebagian besar jenis cmdlet / objek inti memiliki metadata pemformatan yang memberi tahu PowerShell cara menampilkannya dengan cara yang mudah digunakan. Dengan kata lain: hasil pipeing dari perintah ke Out-File dapat digunakan untuk menyimpan keluaran perintah ke file, tanpa kehilangan format yang dilakukan oleh PowerShell.
BartekB
2
Ya, saya pikir itu perbedaan penting yang >tidak persis sama out-file. Jika Anda menyetelnya $PSDefaultParameterValues["Out-File:Encoding"] = "UTF8", ini akan diabaikan oleh >.
wisbucky
3

Set-Contentmendukung -Encoding Byte, sementara Out-Filetidak.

Jadi ketika Anda ingin menulis data biner atau hasil Text.Encoding#GetBytes()ke file, Anda harus menggunakan Set-Content.

SATO Yusuke
sumber
0

Out-file -append atau ">>" sebenarnya dapat mencampur dua pengkodean dalam file yang sama. Bahkan jika file aslinya ascii atau ansi, ini akan menambahkan unicode secara default ke bagian bawahnya. Add-content akan memeriksa encoding dan mencocokkannya sebelum menambahkan. Btw, ekspor-csv default ke ascii (tanpa aksen), dan set-content / add-content ke ansi.

js2010
sumber
0

Ingin menambahkan tentang perbedaan pada encoding:

Windows dengan PowerShell 5.1:

  • Out-File - Pengkodean default adalah utf-16le
  • Set-Content - Pengkodean default adalah us-ascii

Linux dengan PowerShell 7.1:

  • Out-File - Pengkodean default adalah us-ascii
  • Set-Content - Pengkodean default adalah us-ascii
JagWireZ
sumber