PowerShellでテキストを全文読み込む|Get-Content -Rawと行ごとの違い

PowerShellでテキストファイルを読み込んだあと、行数を調べたいのに文字数が返ったり、改行を含めて渡したつもりの文字列が配列になったりすることがあります。画面に同じ内容が表示されても、変数に入る値の形は読み方によって変わります。

Get-Contentは通常、ファイルを行ごとに読み込みます。-Rawを付けると、改行を含む全文を一つの文字列として扱えます。行単位で処理したいときと、JSONなどの全文を渡したいときに合わせて選ぶと、その後の操作が分かりやすくなります。以下の例はWindows PowerShell 5.1とPowerShell 7で使える、UTF-8の小さなテキストファイルを想定しています。


サンプルのテキストファイルを作る

まずは普段のファイルとは別の、新しい作業フォルダーで試してみましょう。次の例はget-content-demoフォルダーを作り、2行のテキストをsample[1].txtへ保存します。同名の作業フォルダーがある場合は別の名前を選び、既存ファイルを上書きしない場所で実行してください。

New-Item -ItemType Directory -Path .\get-content-demo -ErrorAction Stop | Out-Null
Set-Location -LiteralPath .\get-content-demo
Set-Content -LiteralPath '.\sample[1].txt' -Value @('alpha', 'beta') -Encoding UTF8

ファイル名の角括弧は、-Pathではワイルドカードの記法として解釈されることがあります。ここでは入力した名前のまま指定できる-LiteralPathを使います。ファイルの有無も確認したい場合は、Test-PathとLiteralPathで存在を確認する方法も参考になります。

行ごとに読み込んで処理する

各行を取り出して調べたい場合は、-Rawを付けずに読み込みます。結果を@(...)で囲んでおくと、ファイルが1行でも0行でも、行数を配列のCountで扱えます。

$lines = @(Get-Content -LiteralPath '.\sample[1].txt' -Encoding UTF8)
$lines.Count
$lines[0]

出力は次のとおりです。2行が配列に入り、先頭の行はalphaです。各要素には行末の改行文字を含みません。

2
alpha

@(...)を使わずに変数へ代入すると、1行のファイルでは文字列一つが入ります。このときLengthは行数ではなく文字数で、[0]も先頭行ではなく先頭の文字です。複数行で動いた処理が1行だけの入力で変わる場合は、値の形を見直してみてください。

改行を含む全文を一つの文字列で読み込む

ファイル全体を別の処理へ渡す場合は-Rawを使います。文字列として検索したり、JSONの解析へ渡したりするときに、行の配列を自分で結合する必要がなくなります。

$text = Get-Content -LiteralPath '.\sample[1].txt' -Encoding UTF8 -Raw
$text.GetType().Name
$text.Length
$text.Contains("`r`n")

Windows上で先ほどのサンプルを作った場合、結果は次のようになります。

String
13
True

alphaの5文字とbetaの4文字に、2か所のCRLFが加わって13文字です。最後の改行も残ります。LFだけのファイルでは数え方が変わるため、Lengthだけで行数を判定しないようにしましょう。

必要な行だけを読み込む

冒頭の確認なら-TotalCount、末尾の確認なら-Tailを指定できます。次の例は先頭1行と末尾1行をそれぞれ表示します。

Get-Content -LiteralPath '.\sample[1].txt' -Encoding UTF8 -TotalCount 1
Get-Content -LiteralPath '.\sample[1].txt' -Encoding UTF8 -Tail 1
alpha
beta

この読み方は、全文を一つの文字列で得る-Rawと併用できません。ログの末尾だけを見たい場合は-Tailを単独で使い、全文が必要な場合に-Rawを選んでください。

空のファイルと読み取りエラーを確かめる

内容が空のファイルを-Rawで読むと、結果は$nullになります。空文字列として扱いたい処理では、[string]への変換を使えます。行単位で読む場合は@(...)のCountが0になります。

ファイルが存在しない場合や読み取り権限がない場合は、空のファイルとは違ってエラーです。後続処理を止めたいときは-ErrorAction Stopを付け、必要に応じてtry/catchで処理してください。読み取れなかった結果を空の内容として処理しないことが大切です。

文字化けが出る場合は、元ファイルの文字コードと-Encodingの指定を合わせます。Windows PowerShell 5.1とPowerShell 7では既定の文字コードが異なるため、UTF-8と分かっているファイルは上の例のように明示すると読み方をそろえられます。Shift_JISなどのファイルにUTF-8を指定しても正しく読み込めません。

大きなファイルは必要な範囲から読む

-Rawは全文を文字列としてメモリへ載せるため、大きなログやデータでは負担が増えます。必要な行が分かっているなら-TotalCountや-Tailで範囲を絞り、各行を順に処理するなら行単位の読み取りを選んでください。行単位でも結果をすべて変数へ代入すれば保持するデータは増えるので、読み方とその後の処理を合わせて考えると扱いやすくなります。

PowerShellの詳しいパラメーターは、Windows PowerShell 5.1のGet-ContentとPowerShell 7のGet-Contentで確認できます。

このブラウザからの自分のアクセスを解析から除外できます。