ใน PowerShell ความแตกต่างระหว่างOut-FileและSet-Contentอย่างไร หรือAdd-ContentและOut-File -append?
ฉันได้พบถ้าผมใช้ทั้งกับไฟล์เดียวกันข้อความเป็นอย่างmojibaked
(คำถามรองลงมา: >เป็นนามแฝงOut-Fileใช่ไหม?)
ใน PowerShell ความแตกต่างระหว่างOut-FileและSet-Contentอย่างไร หรือAdd-ContentและOut-File -append?
ฉันได้พบถ้าผมใช้ทั้งกับไฟล์เดียวกันข้อความเป็นอย่างmojibaked
(คำถามรองลงมา: >เป็นนามแฝงOut-Fileใช่ไหม?)
คำตอบ:
นี่คือบทสรุปของสิ่งที่ฉันได้อนุมานหลังจากสัมผัสกับ 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 '?'$False
PS > $null | out-file outed.txt
PS > $null | set-content set.txt
PS > md5sum *
f3b25701fe362ec84616a93a45ce9998 *outed.txt
d41d8cd98f00b204e9800998ecf8427e *set.txt
ซึ่งหมายความว่าค่าเริ่มต้นของคำสั่งสองคำสั่งไม่เข้ากันและการผสมกันจะทำให้ข้อความเสียหายดังนั้นควรระบุการเข้ารหัส
ดังที่ Bartek อธิบาย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 ประกอบด้วยพารามิเตอร์เพิ่มเติมดังต่อไปนี้:
Out-File ประกอบด้วยพารามิเตอร์เพิ่มเติมดังต่อไปนี้:
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับพารามิเตอร์เหล่านี้โปรดดูความช่วยเหลือ เช่นget-help out-file -parameter append.
Out-Fileมีปัญหากับสายยาวในบางสถานการณ์ ตัวอย่างเช่น:   $x = [pscustomobject]@{A=('a' * 500); B=('b' * 500)}; $x | Out-File -Path myfile.txt.
                    Out-Fileมีลักษณะการทำงานของการเขียนทับเส้นทางเอาต์พุตเว้นแต่จะมีการตั้งค่าสถานะ-NoClobberและ / หรือ-Appendแฟล็ก Add-Contentจะต่อท้ายเนื้อหาหากเส้นทางเอาต์พุตมีอยู่แล้วตามค่าเริ่มต้น (ถ้าทำได้) ทั้งสองจะสร้างไฟล์หากไม่มีอยู่แล้ว
ความแตกต่างที่น่าสนใจอีกประการหนึ่งคือAdd-Contentจะสร้างไฟล์ที่เข้ารหัส ASCII ตามค่าเริ่มต้นและOut-Fileจะสร้างไฟล์ที่เข้ารหัส endian unicode เล็กน้อยตามค่าเริ่มต้น
>เป็นนามแฝงOut-Fileน้ำตาลประโยคสำหรับ ซึ่งOut-Fileมีการตั้งค่าพารามิเตอร์ที่กำหนดไว้ล่วงหน้า
echo "" > $null | Add-Content abc.txtมันไม่ได้สร้างไฟล์abc.txtในขณะที่ออกจากไฟล์จะ
                    Add-Contentไม่ได้รับอะไรเลย หากAdd-Contentไม่ได้รับอะไรทำไมจึงควรสร้างไฟล์? ในทางกลับกันอาจมีการถามคำถามเดียวกันกับ Out-File
                    gci $folder | Out-File log.txt ; cat log.txtในขณะที่gci $folder | Add-Content log.txt ; cat log.txtเกิดขึ้น
                    Set-Contentที่ใช้งานไฟล์จะไม่สามารถใช้งานได้กับแอปพลิเคชันอื่น
                    ฉันไม่เห็นด้วย ... :)
ดังนั้น:
ls | Add-Content test.txt
และ
ls | Out-File test.txt
จะให้ผลลัพธ์ที่แตกต่างกันโดยสิ้นเชิง
และไม่ ">" ไม่ใช่นามแฝง แต่เป็นตัวดำเนินการเปลี่ยนเส้นทาง (เช่นเดียวกับในเชลล์อื่น ๆ ) และมีข้อ จำกัด ที่ร้ายแรงมาก ... มันจะตัดเส้นแบบเดียวกับที่แสดง Out-File มีพารามิเตอร์ -Width ที่ช่วยคุณหลีกเลี่ยงสิ่งนี้ นอกจากนี้ด้วยตัวดำเนินการเปลี่ยนเส้นทางคุณไม่สามารถตัดสินใจได้ว่าจะใช้การเข้ารหัสใด
HTH Bartek
>และ Out-File คือสิ่งเดียวกัน พวกเขาเรียกรหัสเดียวกัน จาก PowerShell in Action Second Edition ของ Bruce Payette (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.
                    > out-fileถ้าคุณตั้งค่าก็จะถูกละเลยโดย$PSDefaultParameterValues["Out-File:Encoding"] = "UTF8" >
                    Set-Contentรองรับ-Encoding Byteในขณะที่Out-Fileไม่
ดังนั้นเมื่อคุณต้องการที่จะเขียนข้อมูลไบนารีหรือผลของการไปยังแฟ้มที่คุณควรใช้Text.Encoding#GetBytes()Set-Content
Out-file -append หรือ ">>" สามารถผสมการเข้ารหัสสองรายการในไฟล์เดียวกันได้ แม้ว่าไฟล์เดิมจะเป็น ascii หรือ ansi แต่ก็จะเพิ่ม Unicode ไว้ที่ด้านล่างของไฟล์โดยค่าเริ่มต้น Add-content จะตรวจสอบการเข้ารหัสและจับคู่ก่อนต่อท้าย Btw ค่าเริ่มต้น export-csv เป็น ascii (ไม่มีสำเนียง) และ set-content / add-content ไปยัง ansi
ต้องการเพิ่มความแตกต่างในการเข้ารหัส:
Windows พร้อม PowerShell 5.1:
Linux พร้อม PowerShell 7.1:
Set-Contentการเข้ารหัสเริ่มต้น: แปลเป็น(Get-Culture).Textinfo.ANSICodePage(Windows 8.1, Powershell 4.0, CurrentCulturecs-CZ, CurrentUICultureen-GB, ANSICodePage1250, OEMCodePage852ทดสอบโดยใช้'řž'สตริงที่มีรหัสต่างกันในหน้าโค้ดด้านบน)