PowerShellを使用してシステム管理や自動化を行う際、最も頻繁に利用されるコマンドレットの一つがGet-Contentです。
テキストファイルの内容を読み取るというシンプルな役割を持ちながら、その実体は非常に多機能であり、パイプライン処理やログ監視、さらには大規模なデータ処理においても重要な役割を果たします。
Windows環境標準のPowerShell 5.1から、クロスプラットフォーム対応のPowerShell 7.x系へと移行が進む中で、ファイルの文字コード(エンコーディング)の扱いや処理速度の最適化は、エンジニアにとって避けては通れない課題です。
本記事では、基本的な使い方から実務で役立つ応用テクニック、そしてパフォーマンスを劇的に改善するためのコツまで、詳しく解説していきます。
Get-Contentの基本操作
Get-Contentは、指定したパスにあるファイルの内容を一行ずつ読み込み、それをオブジェクトの配列として出力します。
まずは最も基本的な構文を確認しましょう。
ファイルを読み込む
もっともシンプルな使い方は、Pathパラメータにファイル名を指定することです。
# sample.txtの内容を表示する
Get-Content -Path "C:\temp\sample.txt"
1行目のテキストです
2行目のテキストです
3行目のテキストです
PowerShellのGet-Contentが特徴的なのは、読み込んだ内容を単なる「巨大な文字列」としてではなく、「1行を1要素とした配列」として返す点です。
これにより、後続の処理で1行ずつループさせたり、特定の行を抽出したりすることが容易になります。
特定の行数を指定して読み込む
大きなファイルを扱う場合、すべての内容を読み込む必要がないことも多いでしょう。
その場合は、-TotalCountや-Tailパラメータを使用します。
先頭から指定行を読み込む
-TotalCount(別名:-Head)を使用すると、ファイルの先頭から指定した行数分だけを取得できます。
# 先頭の5行だけを読み込む
Get-Content -Path "C:\temp\log.txt" -TotalCount 5
末尾から指定行を読み込む
逆に、最新のログを確認したい場合などは、ファイルの末尾から読み込む-Tailが便利です。
# 末尾の10行だけを読み込む
Get-Content -Path "C:\temp\log.txt" -Tail 10
文字コード(Encoding)の指定
PowerShellで日本語を扱う際に最も注意しなければならないのが、文字化けの問題です。
Windows環境では伝統的に「Shift-JIS (CP932)」が使われてきましたが、近年のシステムやPowerShell Core (7.x)では「UTF-8」が標準となっています。
文字コードを指定して読み込む
ファイルがどの文字コードで保存されているかに応じて、-Encodingパラメータを適切に設定する必要があります。
# Shift-JISのファイルを読み込む場合
Get-Content -Path "sjis_file.txt" -Encoding Default
# UTF-8 (BOMなし) のファイルを読み込む場合
Get-Content -Path "utf8_file.txt" -Encoding utf8
| パラメータ値 | 意味・用途 |
|---|---|
Default | システムの既定(日本語環境では通常 Shift-JIS) |
utf8 | UTF-8形式。PowerShell 7ではBOMなしがデフォルト |
ascii | 7ビットASCII文字セット |
unicode | UTF-16形式 |
PowerShell 5.1を使用している場合、単に-Encoding utf8と指定すると「BOM付きUTF-8」として扱われるため、BOMなしファイルを扱う際には注意が必要です。
一方、PowerShell 7以降ではデフォルトがUTF-8(BOMなし)に統一されているため、文字コードの問題に遭遇する機会は減っています。
リアルタイムでのログ監視(-Wait)
サーバー管理において、アプリケーションが書き出しているログファイルをリアルタイムで監視したい場面があります。
Linuxのtail -fコマンドに相当する機能が、Get-Contentの-Waitパラメータです。
# ログファイルを監視し、追記された内容を即座に表示する
Get-Content -Path "C:\logs\app.log" -Wait -Tail 1
このコマンドを実行すると、PowerShellコンソールは待機状態となり、ファイルに新しい行が追加されるたびにその内容を画面に出力します。
終了するには Ctrl + C を押します。
ファイル読み込みの高速化テクニック
Get-Contentは便利なコマンドレットですが、数万行、数百万行という巨大なファイルを扱う場合、処理が非常に遅くなることがあります。
これは、PowerShellが「1行ずつオブジェクトとしてラップしてパイプラインに流す」というオーバーヘッドを抱えているためです。
パフォーマンスを改善するための主要な方法を2つ紹介します。
1. -Raw パラメータによる一括読み込み
ファイルの内容を1行ずつの配列としてではなく、一つの巨大な文字列として読み込む方法です。
これにより、オブジェクト生成のコストを大幅に削減できます。
# ファイル全体を1つの文字列として読み込む
$content = Get-Content -Path "large_data.txt" -Raw
「-Raw」を使用することで、処理速度は数倍から数十倍に向上する場合があります。
ファイル全体をメモリに読み込んでも問題ないサイズ(数百MB程度まで)であれば、この方法が最も手軽で効果的です。
2. .NETのStreamReaderクラスを活用する
さらに高速な処理が求められる場合、またはファイルサイズがメモリ容量を超える可能性がある場合は、PowerShellの機能ではなく、下位層である.NET Framework / .NETのSystem.IO.StreamReaderを直接使用します。
# .NETのStreamReaderを使用して高速に読み込む
$path = "C:\temp\huge_log.txt"
$reader = [System.IO.StreamReader]::new($path)
try {
while ($line = $reader.ReadLine()) {
# ここで1行ずつの処理を行う
if ($line -match "Error") {
Write-Host $line
}
}
}
finally {
# ファイルを確実に閉じる
$reader.Close()
}
この手法は、メモリ消費を抑えつつ、Get-Contentよりも圧倒的に高速に動作します。
数GBクラスのログファイルをパースする際には、この書き方が推奨されます。
Get-Contentの応用パターン
読み込んだデータをどのように活用するか、実務でよく使われるパターンを紹介します。
特定のキーワードを含む行を抽出する
Select-Stringと組み合わせることで、ファイル内検索が可能です。
しかし、Get-Contentで読み込んでからパイプで渡すよりも、Select-Stringに直接パスを指定するほうが効率的です。
# Get-Contentを使うパターン(やや遅い)
Get-Content -Path "data.log" | Where-Object { $_ -like "*ERROR*" }
# Select-Stringを直接使うパターン(推奨)
Select-String -Path "data.log" -Pattern "ERROR"
複数のファイルを一括で読み込む
ワイルドカードを使用することで、特定のフォルダ内にある複数のファイルをまとめて処理できます。
# 拡張子が .log のファイルをすべて読み込む
$allLogs = Get-Content -Path "C:\logs\*.log"
この時、変数$allLogsには、すべてのファイルの内容が結合された状態で格納されます。
注意点:ファイルロックと権限
ファイルを読み取ろうとした際にエラーが発生するケースがあります。
特によく遭遇するのが「ファイルが別のプロセスで使用されている」というエラーです。
使用中のファイルへのアクセス
他のアプリケーションが書き込み中のファイルを開こうとすると、アクセス拒否エラーが出ることがあります。
その場合は、読み取り専用モードで開くように工夫するか、前述の-Waitパラメータが内部的に共有モードで開く特性を利用することで回避できる場合があります。
また、システム保護された領域(C:\Windows配下など)のファイルを読み取るには、PowerShellを管理者として実行する必要があることを忘れないでください。
まとめ
Get-Contentは、PowerShellにおけるファイル操作の基本でありながら、非常に奥の深いコマンドレットです。
- 基本:行ごとの配列として取得される
- 範囲指定:
-TotalCountや-Tailで必要な分だけ読み取る - 文字コード:環境に合わせて
-Encodingを正しく指定する - 監視:
-Waitでログをリアルタイム追跡する - 最適化:速度重視なら
-Raw、巨大ファイルならStreamReaderを検討する
これらの特性を理解し、用途に応じて使い分けることで、スクリプトの信頼性とパフォーマンスは大きく向上します。
特に、「とりあえずGet-Content」ではなく、データサイズや文字コードを意識した選択ができるようになると、初級者から中級者へのステップアップに繋がります。
日常的なログチェックから大規模なデータ移行作業まで、ぜひ本記事で紹介したテクニックを活用してみてください。
