PowerShellを使用してBOMなしでUTF-8でファイルを書き込む

263
M. Dudley 2011-04-09 05:02.

Out-File UTF-8を使用するとBOMが強制されるようです。

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

PowerShellを使用してBOMなしでUTF-8でファイルを書き込むにはどうすればよいですか?

11 answers

234
M. Dudley 2011-04-09 05:02.

.NETのUTF8Encodingクラスを使用$Falseし、コンストラクターに渡すことは機能しているようです。

$MyRawString = Get-Content -Raw $MyPath $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False [System.IO.File]::WriteAllLines($MyPath, $MyRawString, $Utf8NoBomEncoding)
84
ForNeVeR 2015-10-06 05:03.

適切な今のような方法は、@Romanクズミンが推奨するソリューションを使用することであるコメントで@Mにします。ダドリーの答え:

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

(また、不要なSystem名前空間の説明を削除することで少し短縮しました。デフォルトで自動的に置き換えられます。)

56
Lenny 2016-12-02 14:26.

これはUTFではないと思いましたが、うまくいくように見える非常に単純な解決策を見つけました...

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

私の場合、これにより、ソース形式に関係なく、bomファイルのないutf-8が生成されます。

43
mklement0 2016-01-24 11:44.

注:この回答WindowsPowerShellに適用されます。対照的に、クロスプラットフォームのPowerShell Coreエディション(v6 +)では、すべてのコマンドレットで、BOMのないUTF-8がデフォルトのエンコーディングです
つまりPowerShell [Core]バージョン6以降を使用している場合、デフォルトでBOMのないUTF-8ファイルを取得します(これは-Encoding utf8/-Encoding utf8NoBOMで明示的に要求することもできますが -BOMエンコーディングで取得することもできます-utf8BOM)。


M.ダドリー自身の単純で実用的な答え(およびForNeVeRのより簡潔な再定式化)を補完するために:

便宜上、これは高度な機能Out-FileUtf8NoBomであり、模倣するパイプラインベースの代替Out-File手段です。つまり、次のことを意味します。

  • Out-Fileパイプラインと同じように使用できます。
  • 文字列ではない入力オブジェクトは、と同じように、コンソールに送信した場合と同じようにフォーマットされますOut-File
  • 追加の-UseLFスイッチを使用すると、WindowsスタイルのCRLF改行をUnixスタイルのLFのみの改行に変換できます。

例:

(Get-Content $MyPath) | Out-FileUtf8NoBom $MyPath # Add -UseLF for Unix newlines

(Get-Content $MyPath)で囲まれ(...)ていることに注意してください。これにより、パイプラインを介して結果を送信する前に、ファイル全体が開かれ、完全に読み取られ、閉じられます。これは、同じファイルに書き戻す(その場で更新する)ために必要です。
ただし、一般的に、この手法は2つの理由からお勧めできません。(a)ファイル全体をメモリに収める必要があること、および(b)コマンドが中断されると、データが失われることです。

メモリ使用に関する注意:

  • M. Dudley自身の答えでは、最初にファイルの内容全体をメモリに構築する必要があります。これは、大きなファイルでは問題になる可能性があります。
  • 以下の関数はこれをわずかに改善します。すべての入力オブジェクトは最初にバッファリングされますが、それらの文字列表現が生成され、出力ファイルに1つずつ書き込まれます。

関数のソースコードOut-FileUtf8NoBom

注:この機能はMITライセンスの要点としても利用可能であり、今後も維持されます。

次のコマンドを使用し直接インストールできます(これは安全であると個人的に保証できますが、この方法で直接実行する前に、必ずスクリプトの内容を確認する必要があります)。

# Download and define the function.
irm https://gist.github.com/mklement0/8689b9b5123a9ba11df7214f82a673be/raw/Out-FileUtf8NoBom.ps1 | iex
function Out-FileUtf8NoBom {
<#
.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-File parameters:
    * Only a literal output path is supported, and only as a parameter.
    * -Force is not supported.
    * Conversely, an extra -UseLF switch is supported for using LF-only newlines.
  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 Windows PowerShell
  lacks the ability to write UTF-8 files without a BOM: using -Encoding UTF8 
  invariably prepends a BOM.
  Copyright (c) 2017, 2020 Michael Klement <[email protected]> (http://same2u.net), 
  released under the [MIT license](https://spdx.org/licenses/MIT#licenseText).
#>

  [CmdletBinding()]
  param(
    [Parameter(Mandatory, Position=0)] [string] $LiteralPath,
    [switch] $Append, [switch] $NoClobber,
    [AllowNull()] [int] $Width, [switch] $UseLF,
    [Parameter(ValueFromPipeline)] $InputObject ) #requires -version 3 # Convert the input path to a full one, since .NET's working dir. usually # differs from PowerShell's. $dir = Split-Path -LiteralPath $LiteralPath if ($dir) { $dir = Convert-Path -ErrorAction Stop -LiteralPath $dir } else { $dir = $pwd.ProviderPath}
  $LiteralPath = [IO.Path]::Combine($dir, [IO.Path]::GetFileName($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 System.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 | % { if ($UseLf) {
        $sw.Write($_ + "`n") 
      }
      else {
        $sw.WriteLine($_) 
      }
    }
  } finally {
    $sw.Dispose()
  }

}
19
sc911 2019-03-10 02:59.

始まって、バージョン6 PowerShellのサポートUTF8NoBOMの両方をコードセット内容とアウトファイルもデフォルトエンコードとしてこれを使用しています。

したがって、上記の例では、単純に次のようになります。

$MyFile | Out-File -Encoding UTF8NoBOM $MyPath
17
Lucero 2018-04-24 07:48.

Set-Content代わりにを使用するOut-File場合は、エンコーディングを指定できますByte。これを使用して、バイト配列をファイルに書き込むことができます。これを、BOMを発行しないカスタムUTF8エンコーディングと組み合わせると、望ましい結果が得られます。

# 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
jamhan 2013-05-01 19:22.

このスクリプトは、DIRECTORY1内のすべての.txtファイルをBOMなしのUTF-8に変換し、それらをDIRECTORY2に出力します。

foreach ($i in ls -name DIRECTORY1\*.txt) { $file_content = Get-Content "DIRECTORY1\$i"; [System.IO.File]::WriteAllLines("DIRECTORY2\$i", $file_content);
}
2
frank tan 2017-02-08 19:47.
    [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" 
    }  

ソースPowerShellを使用してファイルからUTF8バイト順マーク(BOM)を削除する方法

2
SATO Yusuke 2017-05-25 03:35.

あなたが使用したい場合[System.IO.File]::WriteAllLines()、あなたは2番目のパラメータをキャストしなければならないString[](のタイプがいる場合$MyFileである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()場合は、2番目のパラメーターをパイプして| 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の結果をBOMなしでUTF-8のファイルに書き込む方法

1
Jaume Suñer Mut 2016-10-04 03:59.

複数のファイルを拡張子でBOMなしのUTF-8に変更します。

$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
Erik Anderson 2016-09-23 09:36.

私が利用する1つの手法は、Out-Fileコマンドレットを使用して出力をASCIIファイルにリダイレクトすることです。

たとえば、Oracleで実行する別のSQLスクリプトを作成するSQLスクリプトを実行することがよくあります。単純なリダイレクト( ">")を使用すると、出力はSQLPlusによって認識されないUTF-16になります。これを回避するには:

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

生成されたスクリプトは、Unicodeの心配なしに別のSQLPlusセッションを介して実行できます。

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

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

驚くほど素晴らしいDropMixミュージックミキシングカードゲームは30ドルで驚くべき取引です

驚くほど素晴らしいDropMixミュージックミキシングカードゲームは30ドルで驚くべき取引です

DropMixはNFC対応のカードゲームで、基本的にはリミックスアーティストになります。現在、Amazonでは$ 30まで下がっており、これまでで最高の価格に匹敵します。ロックバンドで有名なHarmonixによって開発されたDropMixは、おそらく少し野心的すぎるように思われます。結局のところ、ほとんどの人は素晴らしいリズムを持っていませんが、ゲームは驚くほどうまく実行されます。

メアリーJ.ブライジがついにハリウッドウォークオブフェイムスターを獲得

メアリーJ.ブライジがついにハリウッドウォークオブフェイムスターを獲得

写真:APメアリーJ.ブライジは、間もなくハリウッドウォークオブフェイムのスターを獲得します。これは、メアリーJよりもハリウッドウォークオブフェイムのほうが正直なところ恩恵です。

MeltdownとSpectreの脆弱性についてこれまでに知っていることはすべて、簡単な方法で説明されています

MeltdownとSpectreの脆弱性についてこれまでに知っていることはすべて、簡単な方法で説明されています

画像:グラズ工科大学/ NataschaEiblがデザインしたロゴ。MeltdownとSpectreは、攻撃者がシステムメモリに保存されているあらゆる種類の情報にアクセスできるようにする2つの脆弱性に付けられた名前です。

彼のニューヨークの家から追い出されようとしている97歳の第二次世界大戦の獣医。メリーエフィングクリスマス

彼のニューヨークの家から追い出されようとしている97歳の第二次世界大戦の獣医。メリーエフィングクリスマス

日本人に襲われたときに真珠湾にいた97歳の第二次世界大戦のベテランが、ニューヨークのブルックリンから追い出されています。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

投資ノート:Bioscout AU$300万シード

投資ノート:Bioscout AU$300万シード

Bioscoutは、農家を運転席に置くという使命を負っています。Artesian(GrainInnovate)やUniseedと並んで、最新のシードラウンドでチームを支援できることをうれしく思います。問題真菌症による重大な作物の損失は、農民にとって試練であることが証明されています。

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

遠隔医療は、パンデミック後の時代では新しいものではなく、時代遅れの分野でもありません。しかし、業界を詳しく見ると、需要と供給の強力な持続可能性と、米国で絶え間ない革命となる強力な潜在的成長曲線を示しています。

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

2021年は、世界的なベンチャーキャピタル(VC)の資金調達にとって記録的な年でした。DealStreetAsiaによると、東南アジアも例外ではなく、この地域では年間で記録的な25の新しいユニコーンが採掘されました。

ムーアの法則を超えて

ムーアの法則を超えて

計算に対する私たちの欲求とムーアの法則が提供できるものとの間には、指数関数的に増大するギャップがあります。私たちの文明は計算に基づいています—建築と想像力の現在の限界を超える技術を見つけなければなりません。

Language