การใช้ PowerShell เพื่อเขียนไฟล์ใน UTF-8 โดยไม่มี BOM


246

Out-File ดูเหมือนว่าจะบังคับ BOM เมื่อใช้ UTF-8:

$MyFile = Get-Content $MyPath
$MyFile | Out-File -Encoding "UTF8" $MyPath

ฉันจะเขียนไฟล์ใน UTF-8 ที่ไม่มี BOM โดยใช้ PowerShell ได้อย่างไร


23
BOM = เครื่องหมายคำสั่งซื้อแบบไบต์ วางสามตัวที่จุดเริ่มต้นของไฟล์ (0xEF, 0xBB, 0xBF) ที่ดูเหมือน ""
สัญญาณ 15

40
มันน่าผิดหวังอย่างไม่น่าเชื่อ แม้แต่โมดูลของบุคคลที่สามก็มีมลภาวะเช่นพยายามอัปโหลดไฟล์ผ่าน SSH หรือไม่ BOM! "ใช่ทำลายไฟล์ทุกไฟล์เสียแล้วมันฟังดูดีนะ" -Microsoft
MichaelGG

3
การเข้ารหัสเริ่มต้นคือ UTF8NoBOM เริ่มต้นด้วย Powershell รุ่น 6.0 docs.microsoft.com/en-us/powershell/module/ …
Paul Shiryaev

พูดคุยเกี่ยวกับการทำลายความเข้ากันได้ย้อนหลัง ...
Dragas

คำตอบ:


220

การใช้UTF8Encodingคลาสของ. NET และส่งผ่าน$Falseไปยังตัวสร้างดูเหมือนจะทำงาน:

$MyRawString = Get-Content -Raw $MyPath
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines($MyPath, $MyRawString, $Utf8NoBomEncoding)

42
ฮึฉันหวังว่านั่นจะไม่ใช่วิธีเดียว
Scott Muc

114
บรรทัดเดียว[System.IO.File]::WriteAllLines($MyPath, $MyFile)ก็พอ WriteAllLinesโอเวอร์โหลดนี้เขียน UTF8 ที่แน่นอนโดยไม่มี BOM
Roman Kuzmin

6
สร้างคำขอคุณลักษณะ MSDN ที่นี่: connect.microsoft.com/PowerShell/feedbackdetail/view/1137121/…
Groostav

3
โปรดทราบว่าWriteAllLinesดูเหมือนว่าจะต้อง$MyPathมีแน่นอน
sschuberth

10
@xdhmoore ได้รับไดเรกทอรีปัจจุบันจากWriteAllLines [System.Environment]::CurrentDirectoryหากคุณเปิด PowerShell แล้วเปลี่ยนไดเรกทอรีปัจจุบันของคุณ (โดยใช้cdหรือSet-Location) จากนั้น[System.Environment]::CurrentDirectoryจะไม่มีการเปลี่ยนแปลงและไฟล์จะอยู่ในไดเรกทอรีที่ไม่ถูกต้อง [System.Environment]::CurrentDirectory = (Get-Location).Pathคุณสามารถทำงานรอบนี้โดย
Shayan Toqraee

79

เหมาะสมวิธีที่เป็นอยู่ในตอนนี้คือการใช้วิธีการแก้ปัญหาที่แนะนำโดย @Roman Kuzmin ในความคิดเห็นเพื่อวิสัย ดัดลีย์ตอบ :

[IO.File]::WriteAllLines($filename, $content)

(ฉันยังย่อให้สั้นลงเล็กน้อยโดยการSystemล้างการชี้แจงเนมสเปซที่ไม่จำเป็น- มันจะถูกแทนที่โดยอัตโนมัติตามค่าเริ่มต้น)


2
นี่ (ไม่ว่าด้วยเหตุผลใดก็ตาม) ไม่ได้ลบ BOM สำหรับฉันซึ่งเป็นคำตอบที่ยอมรับ
Liam

@ เลียมอาจเป็น PowerShell หรือ. NET รุ่นเก่าบ้าง
ForNeVeR

1
ฉันเชื่อว่าฟังก์ชัน. NET WriteAllLines รุ่นเก่ากว่านั้นเขียน BOM ตามค่าเริ่มต้น ดังนั้นอาจเป็นปัญหารุ่น
ประมาทครั้งยิ่งใหญ่ที่สุดใน

2
ยืนยันกับเขียนด้วย BOM ใน Powershell 3 แต่ไม่มี BOM ใน Powershell 4 ฉันต้องใช้คำตอบดั้งเดิมของ M. Dudley
chazbot7

2
ดังนั้นมันจึงทำงานบน Windows 10 ที่ติดตั้งโดยค่าเริ่มต้น :) นอกจากนี้การปรับปรุงที่แนะนำ:[IO.File]::WriteAllLines(($filename | Resolve-Path), $content)
Johny Skovdal

50

ฉันคิดว่าสิ่งนี้จะไม่เป็น UTF แต่ฉันเพิ่งค้นพบวิธีแก้ปัญหาง่ายๆที่ดูเหมือนว่าจะทำงาน ...

Get-Content path/to/file.ext | out-file -encoding ASCII targetFile.ext

สำหรับฉันผลลัพธ์นี้เป็น utf-8 โดยไม่มีไฟล์ bom โดยไม่คำนึงถึงรูปแบบของแหล่งที่มา


8
สิ่งนี้ใช้ได้สำหรับฉันยกเว้นฉันใช้-encoding utf8ตามความต้องการของฉัน
Chim Chimz

1
ขอบคุณมาก. ฉันกำลังทำงานกับดัมพ์บันทึกของเครื่องมือ - ซึ่งมีแท็บอยู่ภายใน UTF-8 ไม่ทำงาน ASCII แก้ปัญหาได้ ขอบคุณ
user1529294

44
ใช่-Encoding ASCIIหลีกเลี่ยงปัญหา BOM แต่เห็นได้ชัดว่าคุณได้รับอักขระ ASCII 7 บิตเท่านั้น ระบุว่า ASCII เป็นส่วนหนึ่งของ UTF-8, แฟ้มผลเป็นเทคนิคที่ยัง UTF-8 ไฟล์ที่ถูกต้อง แต่ทุกอักขระที่ไม่ใช่ ASCII ในการป้อนข้อมูลของคุณจะถูกแปลงเป็นตัวอักษร?ตัวอักษร
mklement0

4
@ChimChimz ฉันตั้งใจโหวตความคิดเห็นของคุณ แต่-encoding utf8ยังส่งออก UTF-8 ด้วย BOM :(
TheDudeAbides

33

หมายเหตุ: คำตอบนี้ใช้กับWindows PowerShell ; ในทางตรงกันข้ามใน PowerShell Core edition (v6 +) ข้ามแพลตฟอร์มUTF-8 ที่ไม่มี BOMคือการเข้ารหัสเริ่มต้นสำหรับทุก cmdlet
ในคำอื่น ๆ : หากคุณกำลังใช้PowerShell [หลัก] รุ่น 6 หรือสูงกว่าคุณจะได้รับ BOM น้อย UTF-8 ไฟล์โดยค่าเริ่มต้น (ซึ่งคุณสามารถขออย่างชัดเจนด้วย-Encoding utf8/ -Encoding utf8NoBOMขณะที่คุณจะได้รับกับ -BOM เข้ารหัสด้วย-utf8BOM)


เพื่อเติมเต็มคำตอบที่ง่ายและปฏิบัติของ M. Dudley (และการปฏิรูปที่กระชับยิ่งขึ้นของ ForNeVeR ):

เพื่อความสะดวกต่อไปนี้เป็นฟังก์ชั่นขั้นสูงOut-FileUtf8NoBom, ทางเลือกที่ท่อตามที่เลียนแบบOut-Fileซึ่งหมายถึง:

  • คุณสามารถใช้มันได้เหมือนOut-Fileในท่อ
  • Out-Fileวัตถุการป้อนข้อมูลที่ไม่ได้รับสายที่มีรูปแบบที่พวกเขาจะเป็นอย่างไรถ้าคุณส่งพวกเขาไปยังคอนโซลเช่นเดียวกับ

ตัวอย่าง:

(Get-Content $MyPath) | Out-FileUtf8NoBom $MyPath

ให้สังเกตว่า(Get-Content $MyPath)มีการปิดล้อมไว้ใน(...)ที่ใดเพื่อให้แน่ใจว่าไฟล์ทั้งหมดถูกเปิดอ่านเต็มและปิดก่อนที่จะส่งผลลัพธ์ผ่านไปป์ไลน์ นี่เป็นสิ่งที่จำเป็นเพื่อให้สามารถเขียนกลับไปที่ไฟล์เดียวกัน (อัปเดตในที่ )
โดยทั่วไปแม้ว่าเทคนิคนี้ไม่แนะนำให้เลือกด้วยเหตุผล 2 ประการ: (a) ไฟล์ทั้งหมดจะต้องพอดีกับหน่วยความจำและ (b) หากคำสั่งถูกขัดจังหวะข้อมูลจะหายไป

หมายเหตุเกี่ยวกับการใช้หน่วยความจำ :

  • คำตอบของเอ็มดัดลีย์ต้องการให้เนื้อหาไฟล์ทั้งหมดถูกสร้างขึ้นในหน่วยความจำก่อนซึ่งอาจเป็นปัญหากับไฟล์ขนาดใหญ่
  • ฟังก์ชั่นด้านล่างปรับปรุงในเรื่องนี้เพียงเล็กน้อย: วัตถุอินพุตทั้งหมดยังคงถูกบัฟเฟอร์ก่อน แต่การแทนค่าสตริงของพวกเขาจะถูกสร้างและเขียนลงในไฟล์เอาต์พุตทีละตัว

ซอร์สโค้ดของOut-FileUtf8NoBom (มีให้ในฐานะ Gist ที่ได้รับอนุญาต MIT )

<#
.SYNOPSIS
  Outputs to a UTF-8-encoded file *without a BOM* (byte-order mark).

.DESCRIPTION
  Mimics the most important aspects of Out-File:
  * Input objects are sent to Out-String first.
  * -Append allows you to append to an existing file, -NoClobber prevents
    overwriting of an existing file.
  * -Width allows you to specify the line width for the text representations
     of input objects that aren't strings.
  However, it is not a complete implementation of all Out-String parameters:
  * Only a literal output path is supported, and only as a parameter.
  * -Force is not supported.

  Caveat: *All* pipeline input is buffered before writing output starts,
          but the string representations are generated and written to the target
          file one by one.

.NOTES
  The raison d'être for this advanced function is that, as of PowerShell v5,
  Out-File still lacks the ability to write UTF-8 files without a BOM:
  using -Encoding UTF8 invariably prepends a BOM.

#>
function Out-FileUtf8NoBom {

  [CmdletBinding()]
  param(
    [Parameter(Mandatory, Position=0)] [string] $LiteralPath,
    [switch] $Append,
    [switch] $NoClobber,
    [AllowNull()] [int] $Width,
    [Parameter(ValueFromPipeline)] $InputObject
  )

  #requires -version 3

  # Make sure that the .NET framework sees the same working dir. as PS
  # and resolve the input path to a full path.
  [System.IO.Directory]::SetCurrentDirectory($PWD.ProviderPath) # Caveat: Older .NET Core versions don't support [Environment]::CurrentDirectory
  $LiteralPath = [IO.Path]::GetFullPath($LiteralPath)

  # If -NoClobber was specified, throw an exception if the target file already
  # exists.
  if ($NoClobber -and (Test-Path $LiteralPath)) {
    Throw [IO.IOException] "The file '$LiteralPath' already exists."
  }

  # Create a StreamWriter object.
  # Note that we take advantage of the fact that the StreamWriter class by default:
  # - uses UTF-8 encoding
  # - without a BOM.
  $sw = New-Object IO.StreamWriter $LiteralPath, $Append

  $htOutStringArgs = @{}
  if ($Width) {
    $htOutStringArgs += @{ Width = $Width }
  }

  # Note: By not using begin / process / end blocks, we're effectively running
  #       in the end block, which means that all pipeline input has already
  #       been collected in automatic variable $Input.
  #       We must use this approach, because using | Out-String individually
  #       in each iteration of a process block would format each input object
  #       with an indvidual header.
  try {
    $Input | Out-String -Stream @htOutStringArgs | % { $sw.WriteLine($_) }
  } finally {
    $sw.Dispose()
  }

}

16

การเริ่มต้นจากรุ่น 6 PowerShell รองรับการUTF8NoBOMเข้ารหัสทั้งสำหรับชุดเนื้อหาและไฟล์ออกและยังใช้สิ่งนี้เป็นการเข้ารหัสเริ่มต้น

ดังนั้นในตัวอย่างข้างต้นควรเป็นดังนี้:

$MyFile | Out-File -Encoding UTF8NoBOM $MyPath

@ RaúlSalinas-Monteagudo คุณเป็นรุ่นอะไร
John Bentley

ดี รุ่นตรวจสอบ FYI ด้วย$PSVersionTable.PSVersion
KCD

14

เมื่อใช้Set-ContentแทนคุณOut-Fileสามารถระบุการเข้ารหัสByteซึ่งสามารถใช้ในการเขียนอาร์เรย์ไบต์ลงในไฟล์ เมื่อรวมกับการเข้ารหัส UTF8 แบบกำหนดเองซึ่งไม่ปล่อย BOM จะให้ผลลัพธ์ที่ต้องการ:

# This variable can be reused
$utf8 = New-Object System.Text.UTF8Encoding $false

$MyFile = Get-Content $MyPath -Raw
Set-Content -Value $utf8.GetBytes($MyFile) -Encoding Byte -Path $MyPath

ความแตกต่างในการใช้งาน[IO.File]::WriteAllLines()หรือคล้ายกันคือควรทำงานได้ดีกับรายการและพา ธ ทุกประเภท


5

สคริปต์นี้จะแปลงเป็น UTF-8 โดยไม่มี BOM ไฟล์. txt ทั้งหมดใน DIRECTORY1 และส่งออกเป็น DIRECTORY2

foreach ($i in ls -name DIRECTORY1\*.txt)
{
    $file_content = Get-Content "DIRECTORY1\$i";
    [System.IO.File]::WriteAllLines("DIRECTORY2\$i", $file_content);
}

อันนี้ล้มเหลวโดยไม่มีการเตือนใด ๆ ฉันควรใช้ powershell รุ่นใดเพื่อเรียกใช้
darksoulsong

3
โซลูชัน WriteAllLines ใช้งานได้ดีสำหรับไฟล์ขนาดเล็ก อย่างไรก็ตามฉันต้องการทางออกสำหรับไฟล์ที่มีขนาดใหญ่ขึ้น ทุกครั้งที่ฉันพยายามใช้สิ่งนี้กับไฟล์ที่ใหญ่ขึ้นฉันจะได้รับข้อผิดพลาด OutOfMemory
BermudaLamb

2
    [System.IO.FileInfo] $file = Get-Item -Path $FilePath 
    $sequenceBOM = New-Object System.Byte[] 3 
    $reader = $file.OpenRead() 
    $bytesRead = $reader.Read($sequenceBOM, 0, 3) 
    $reader.Dispose() 
    #A UTF-8+BOM string will start with the three following bytes. Hex: 0xEF0xBB0xBF, Decimal: 239 187 191 
    if ($bytesRead -eq 3 -and $sequenceBOM[0] -eq 239 -and $sequenceBOM[1] -eq 187 -and $sequenceBOM[2] -eq 191) 
    { 
        $utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False) 
        [System.IO.File]::WriteAllLines($FilePath, (Get-Content $FilePath), $utf8NoBomEncoding) 
        Write-Host "Remove UTF-8 BOM successfully" 
    } 
    Else 
    { 
        Write-Warning "Not UTF-8 BOM file" 
    }  

แหล่งที่มาวิธีลบ UTF8 Byte Order Mark (BOM) ออกจากไฟล์โดยใช้ PowerShell


2

หากคุณต้องการใช้[System.IO.File]::WriteAllLines()คุณควรแปลงพารามิเตอร์ตัวที่สองเป็นString[](หากชนิดของ$MyFileis Object[]) และระบุพา ธ สัมบูรณ์ด้วย$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($MyPath)เช่น:

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
Get-ChildItem | ConvertTo-Csv | Set-Variable MyFile
[System.IO.File]::WriteAllLines($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($MyPath), [String[]]$MyFile, $Utf8NoBomEncoding)

หากคุณต้องการใช้[System.IO.File]::WriteAllText()บางครั้งคุณควร| Out-String |ไพพ์พารามิเตอร์ที่สองเข้าไปเพื่อเพิ่ม CRLF ไปที่ท้ายบรรทัดแต่ละบรรทัดอย่างชัดเจน (โดยเฉพาะเมื่อคุณใช้กับConvertTo-Csv)

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
Get-ChildItem | ConvertTo-Csv | Out-String | Set-Variable tmp
[System.IO.File]::WriteAllText("/absolute/path/to/foobar.csv", $tmp, $Utf8NoBomEncoding)

หรือคุณสามารถใช้[Text.Encoding]::UTF8.GetBytes()กับSet-Content -Encoding Byte:

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
Get-ChildItem | ConvertTo-Csv | Out-String | % { [Text.Encoding]::UTF8.GetBytes($_) } | Set-Content -Encoding Byte -Path "/absolute/path/to/foobar.csv"

ดู: วิธีการเขียนผลลัพธ์ของ ConvertTo-Csv ไปยังไฟล์ใน UTF-8 โดยไม่มี BOM


ตัวชี้ที่ดี ข้อเสนอแนะ /: ทางเลือกที่ง่ายกว่า$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($MyPath)คือConvert-Path $MyPath; หากคุณต้องการให้แน่ใจว่ามี CRLF ต่อท้ายให้ใช้[System.IO.File]::WriteAllLines()คู่กับสตริงอินพุตเดียว (ไม่จำเป็นOut-String)
mklement0

0

เทคนิคหนึ่งที่ฉันใช้คือเปลี่ยนเส้นทางเอาต์พุตไปยังไฟล์ ASCII โดยใช้Out-File cmdlet

ตัวอย่างเช่นฉันมักจะเรียกใช้สคริปต์ SQL ที่สร้างสคริปต์ SQL อื่นเพื่อรันใน Oracle ด้วยการเปลี่ยนเส้นทางแบบง่าย (">") ผลลัพธ์จะเป็น UTF-16 ซึ่ง SQLPlus ไม่รู้จัก ในการหลีกเลี่ยงสิ่งนี้:

sqlplus -s / as sysdba "@create_sql_script.sql" |
Out-File -FilePath new_script.sql -Encoding ASCII -Force

สคริปต์ที่สร้างขึ้นสามารถถูกเรียกใช้งานผ่านเซสชัน SQLPlus อื่นโดยไม่ต้องมี Unicode กังวล:

sqlplus / as sysdba "@new_script.sql" |
tee new_script.log

4
ใช่-Encoding ASCIIหลีกเลี่ยงปัญหา BOM แต่คุณเห็นได้ชัดเพียง แต่ได้รับการสนับสนุนสำหรับอักขระ ASCII 7 บิต ระบุว่า ASCII เป็นส่วนหนึ่งของ UTF-8, แฟ้มผลเป็นเทคนิคที่ยัง UTF-8 ไฟล์ที่ถูกต้อง แต่ทุกอักขระที่ไม่ใช่ ASCII ในการป้อนข้อมูลของคุณจะถูกแปลงเป็นตัวอักษร?ตัวอักษร
mklement0

คำตอบนี้ต้องการคะแนนโหวตมากกว่า ความไม่ลงรอยกันของ sqlplus กับ BOM เป็นสาเหตุของอาการปวดหัวมากมาย
Amit Naidu

0

เปลี่ยนไฟล์หลายไฟล์โดยขยายเป็น UTF-8 โดยไม่มี BOM:

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
foreach($i in ls -recurse -filter "*.java") {
    $MyFile = Get-Content $i.fullname 
    [System.IO.File]::WriteAllLines($i.fullname, $MyFile, $Utf8NoBomEncoding)
}

0

ไม่ว่าจะด้วยเหตุผลใดก็ตามการWriteAllLinesโทรยังคงสร้าง BOM สำหรับฉันด้วยUTF8Encodingอาร์กิวเมนต์BOMless และไม่ได้ทำ แต่สิ่งต่อไปนี้ใช้ได้กับฉัน:

$bytes = gc -Encoding byte BOMthetorpedoes.txt
[IO.File]::WriteAllBytes("$(pwd)\BOMthetorpedoes.txt", $bytes[3..($bytes.length-1)])

ฉันต้องทำให้เส้นทางไฟล์สมบูรณ์เพื่อให้ใช้งานได้ มิฉะนั้นจะเขียนไฟล์ไปยังเดสก์ท็อปของฉัน นอกจากนี้ฉันคิดว่ามันใช้งานได้ก็ต่อเมื่อคุณรู้ว่า BOM ของคุณคือ 3 ไบต์ ฉันไม่รู้เลยว่ามันน่าเชื่อถือแค่ไหนที่จะคาดหวังรูปแบบ / ความยาว BOM ที่ได้รับจากการเข้ารหัส

นอกจากนี้ตามที่เขียนไว้อาจใช้งานได้เฉพาะในกรณีที่ไฟล์ของคุณอยู่ในอาร์เรย์ PowerShell ซึ่งดูเหมือนว่าจะมีขีดจำกัดความยาวของค่าต่ำกว่า[int32]::MaxValueในเครื่องของฉัน


1
WriteAllLinesโดยไม่ต้องมีการเข้ารหัสการเข้ารหัสไม่เคยเขียน BOM เองแต่เป็นไปได้ที่สตริงของคุณจะเริ่มต้นด้วยอักขระ BOM ( U+FEFF) ซึ่งการเขียนได้สร้าง UTF-8 BOM อย่างมีประสิทธิภาพ เช่น: $s = [char] 0xfeff + 'hi'; [io.file]::WriteAllText((Convert-Path t.txt), $s)(ละเว้นการ[char] 0xfeff + เพื่อดูว่าไม่มีการเขียน BOM)
mklement0

1
สำหรับการเขียนไปยังตำแหน่งอื่นโดยไม่คาดคิด: ปัญหาคือโดยทั่วไปแล้ว. NET Framework จะมีไดเรกทอรีปัจจุบันแตกต่างจาก PowerShell; คุณสามารถซิงค์พวกเขาเป็นครั้งแรกด้วย[Environment]::CurrentDirectory = $PWD.ProviderPathหรือเป็นทางเลือกที่ทั่วไปมากขึ้นกับ"$(pwd)\..."วิธีการของคุณ(ดีกว่า: "$pwd\..."ดียิ่งขึ้น: "$($pwd.ProviderPath)\..."หรือ(Join-Path $pwd.ProviderPath ...)) ใช้(Convert-Path BOMthetorpedoes.txt)
mklement0

ขอบคุณฉันไม่ทราบว่าอาจมีอักขระ BOM เดียวกับการแปลง BOM UTF-8
xdhmoore

1
ทั้งหมด BOM ลำดับไบต์ (ลายเซ็น Unicode) ในความเป็นจริงเป็นตัวแทนไบต์การเข้ารหัสที่เกี่ยวข้องของนามธรรมอักขระ Unicode เดียว U+FEFF
mklement0

อาโอเค. ดูเหมือนจะทำให้สิ่งต่าง ๆ ง่ายขึ้น
xdhmoore

-2

สามารถใช้ด้านล่างเพื่อรับ UTF8 โดยไม่มี BOM

$MyFile | Out-File -Encoding ASCII

4
ไม่มันจะแปลงเอาท์พุทเป็นเพจรหัส ANSI ปัจจุบัน (cp1251 หรือ cp1252 เป็นต้น) ไม่ใช่ UTF-8 เลย!
ForNeVeR

1
ขอบคุณโรบิน สิ่งนี้อาจใช้ไม่ได้กับการเขียนไฟล์ UTF-8 โดยไม่มี BOM แต่ตัวเลือก -Encoding ASCII จะลบ BOM ด้วยวิธีนี้ฉันสามารถสร้างไฟล์ค้างคาวสำหรับ gvim ไฟล์. bat ได้รับการสะดุดที่ BOM
เกร็ก

3
@ForNeVeR: คุณถูกต้องที่เข้ารหัสASCIIไม่ได้เป็น UTF-8 แต่มันไม่ ALS เพจรหัส ANSI ปัจจุบัน - คุณกำลังความคิดของDefault; ASCIIแท้จริงคือการเข้ารหัส ASCII 7 บิตโดย codepoints> = 128 การแปลงเป็น?อินสแตนซ์ตัวอักษร
mklement0

1
@ForNeVeR: คุณอาจนึกถึง "ANSI" หรือ " Extended ASCII" ลองนี้เพื่อตรวจสอบว่า-Encoding ASCIIเป็นจริง 7 บิต ASCII เท่านั้น: 'äb' | out-file ($f = [IO.Path]::GetTempFilename()) -encoding ASCII; '?b' -eq $(Get-Content $f; Remove-Item $f)- The ได้รับการทับศัพท์ไปä ?ในทางตรงกันข้าม-Encoding Default("ANSI") จะเก็บรักษาไว้อย่างถูกต้อง
mklement0

3
@rob นี่คือคำตอบที่สมบูรณ์แบบสำหรับทุกคนที่ไม่ต้องการ utf-8 หรืออะไรก็ตามที่แตกต่างจาก ASCII และไม่สนใจที่จะเข้าใจการเข้ารหัสและจุดประสงค์ของยูนิโค้ด คุณสามารถใช้เป็น utf-8 ได้เนื่องจากอักขระ utf-8 ที่เทียบเท่ากับอักขระ ASCII ทั้งหมดเหมือนกัน (หมายถึงการแปลงไฟล์ ASCII ไปเป็นผลลัพธ์ไฟล์ utf-8 ในไฟล์ที่เหมือนกัน (หากไม่มี BOM) สำหรับทุกคนที่มีตัวละครที่ไม่ใช่ ASCII ในข้อความของพวกเขาคำตอบนี้เป็นเพียงความเท็จและทำให้เข้าใจผิด
ทีเอ็นที

-3

อันนี้ใช้ได้กับฉัน (ใช้ "Default" แทน "UTF8"):

$MyFile = Get-Content $MyPath
$MyFile | Out-File -Encoding "Default" $MyPath

ผลลัพธ์คือ ASCII ที่ไม่มี BOM


1
ตามเอกสารออกไฟล์ที่ระบุการDefaultเข้ารหัสจะใช้หน้ารหัส ANSI ปัจจุบันของระบบซึ่งไม่ใช่ UTF-8 ตามที่ฉันต้องการ
M. Dudley

สิ่งนี้ดูเหมือนจะใช้ได้กับฉันอย่างน้อยก็สำหรับ Export-CSV หากคุณเปิดไฟล์ผลลัพธ์ในโปรแกรมแก้ไขที่เหมาะสมการเข้ารหัสไฟล์คือ UTF-8 ที่ไม่มี BOM และไม่ใช่ Western Latin ISO 9 อย่างที่ฉันคาดไว้กับ ASCII
eythort

ผู้แก้ไขหลายคนเปิดไฟล์เป็น UTF-8 หากพวกเขาไม่สามารถตรวจจับการเข้ารหัส
2560
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.