Out-File
UTF-8を使用するとBOMが強制されるようです。
$MyFile = Get-Content $MyPath
$MyFile | Out-File -Encoding "UTF8" $MyPath
PowerShellを使用してBOMなしでUTF-8でファイルを書き込むにはどうすればよいですか?
.NETのUTF8Encoding
クラスを使用$False
し、コンストラクターに渡すことは機能しているようです。
$MyRawString = Get-Content -Raw $MyPath $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False [System.IO.File]::WriteAllLines($MyPath, $MyRawString, $Utf8NoBomEncoding)
適切な今のような方法は、@Romanクズミンが推奨するソリューションを使用することであるコメントで@Mにします。ダドリーの答え:
[IO.File]::WriteAllLines($filename, $content)
(また、不要なSystem
名前空間の説明を削除することで少し短縮しました。デフォルトで自動的に置き換えられます。)
これはUTFではないと思いましたが、うまくいくように見える非常に単純な解決策を見つけました...
Get-Content path/to/file.ext | out-file -encoding ASCII targetFile.ext
私の場合、これにより、ソース形式に関係なく、bomファイルのないutf-8が生成されます。
注:この回答は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)コマンドが中断されると、データが失われることです。
メモリ使用に関する注意:
関数のソースコード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()
}
}
始まって、バージョン6 PowerShellのサポートUTF8NoBOM
の両方をコードセット内容とアウトファイルもデフォルトエンコードとしてこれを使用しています。
したがって、上記の例では、単純に次のようになります。
$MyFile | Out-File -Encoding UTF8NoBOM $MyPath
の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()
または同様のものとの違いは、実際のファイルパスだけでなく、あらゆるタイプのアイテムとパスで正常に機能することです。
このスクリプトは、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);
}
[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)を削除する方法
あなたが使用したい場合[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のファイルに書き込む方法
複数のファイルを拡張子で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)
}
私が利用する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
特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。
ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。
ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。
DropMixはNFC対応のカードゲームで、基本的にはリミックスアーティストになります。現在、Amazonでは$ 30まで下がっており、これまでで最高の価格に匹敵します。ロックバンドで有名なHarmonixによって開発されたDropMixは、おそらく少し野心的すぎるように思われます。結局のところ、ほとんどの人は素晴らしいリズムを持っていませんが、ゲームは驚くほどうまく実行されます。
写真:APメアリーJ.ブライジは、間もなくハリウッドウォークオブフェイムのスターを獲得します。これは、メアリーJよりもハリウッドウォークオブフェイムのほうが正直なところ恩恵です。
画像:グラズ工科大学/ NataschaEiblがデザインしたロゴ。MeltdownとSpectreは、攻撃者がシステムメモリに保存されているあらゆる種類の情報にアクセスできるようにする2つの脆弱性に付けられた名前です。
日本人に襲われたときに真珠湾にいた97歳の第二次世界大戦のベテランが、ニューヨークのブルックリンから追い出されています。
Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday
シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。
オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。
Bioscoutは、農家を運転席に置くという使命を負っています。Artesian(GrainInnovate)やUniseedと並んで、最新のシードラウンドでチームを支援できることをうれしく思います。問題真菌症による重大な作物の損失は、農民にとって試練であることが証明されています。
遠隔医療は、パンデミック後の時代では新しいものではなく、時代遅れの分野でもありません。しかし、業界を詳しく見ると、需要と供給の強力な持続可能性と、米国で絶え間ない革命となる強力な潜在的成長曲線を示しています。
2021年は、世界的なベンチャーキャピタル(VC)の資金調達にとって記録的な年でした。DealStreetAsiaによると、東南アジアも例外ではなく、この地域では年間で記録的な25の新しいユニコーンが採掘されました。
計算に対する私たちの欲求とムーアの法則が提供できるものとの間には、指数関数的に増大するギャップがあります。私たちの文明は計算に基づいています—建築と想像力の現在の限界を超える技術を見つけなければなりません。