SEブログ

【PowerShell】テキストファイルの操作をする

こんにちは!SE ブログの相馬です。

 

 

 

今回は、テキストファイルの操作を PowerShell でやってみました。テキストファイルの操作とは、例えば該当のファイルがあるか確認したり、ファイルの中身を参照したり、ファイルを検索したり等、する事を指します。

 

 

この操作ができるようになりますと、例えば PowerShell で条件文と組み合わせをして「ファイルやフォルダがある場合は A の処理をして、無い場合は B の処理をするという事ができるようになります。」ですので、実際この操作はよく使うと思いますので覚えておくと良いでしょう。

 

 

ここではコマンドレット別、処理別にスクリプトを分けていますので、一つずつ覚えてゆきましょう。それではまず、条件文で指定のフォルダにテキストファイルがあるかどうかの条件文になります。結果はそれぞれ Write-Output で文字列を返すようにしています。

 

 

 

ファイルの中身を表示

 

 

Test-Path を使った処理

 

 

Test-Path コマンドレットは、指定の場所にファイルやフォルダが存在するかどうかを確認します。また、レジストリのキーワードの存在も確認することができます。返り値として、存在する場合は True、存在しない場合は False を返します。

 

 

処理の内容としては、if 分で指定の場所にファイルがあるかないかで、Write-Output でコンソールに文字列を表示します。

 

 

if (Test-Path "C:\temp\script\users.txt") {

    Write-Output "ファイルがあります。"

} else {

    Write-Output "ファイルはありません。"

}


# 実行結果
ファイルがある場合は「ファイルがあります。」と返ってきます。
ファイルが無い場合は「ファイルはありません。」と返ってきます。

 

 

 

Get-Content を使った処理

 

 

Get-Content コマンドレットは、ファイルの中身をコンソールに表示するコマンドレットです。Linux であれば、cat や tail のようなものです。ですので、例えば、ログファイルのようにファイルの中身が沢山ある場合、最後の何行かだけコンソールに出力する事ももちろんできます。

 

 

それでは、上で使った Test-Path と同じような処理ですが、ファイルが存在する場合、Get-Content でファイルの中身をコンソールに表示する事をやってみます。

 

 

サンプル① では単純にファイルの中身を全て表示します。

サンプル② ではファイルの中身から最後の 5 行だけ表示します。

サンプル③ ではファイルの中身から指定した行だけ表示します。

(スクリプト内で Tech-Path で参照しているファイル名は同じですが、実際中身は異なっています。)

 

サンプル①:ファイルの中身を全て表示

 

if (Test-Path "C:\temp\scripts\users.txt") {

    Get-Content "C:\temp\scripts\users.txt"

} else {

    Write-Output "ファイルはありません。"

}


# 実行結果(ファイルが存在する場合)

浦島太郎
乙姫
ビルゲイツ

 

 

 

サンプル②:ファイルの中身から最後の 5 行だけ表示します。Get-Content コマンドレットで、指定の行だけコンソールに出力する事もできます。Get-Content のファイル指定の後に -tail と指定の行を書きます。ここでは 5 行表示したいので -tail 5 と書いてます。

 

if (Test-Path "C:\temp\scripts\users.txt") {

    Get-Content "C:\temp\scripts\users.txt" -tail 5

} else {

    Write-Output "ファイルはありません。"

}


# 実行結果

ビルゲイツ
キャプテンアメリカ
ハルク
キャプテン翼
ケンシロウ

 

 

 

サンプル③:指定の行だけコンソールに表示します。。Get-Content のファイル指定の後にカギカッコと指定の行を書きます。行と書いていますが、実際は配列になりますので、0 から始まります。ですので、3 行目にビルゲイツが書いていますが、0, 1, 2 と数えているので [2] と指定します。

 


if (Test-Path "C:\temp\scripts\users.txt") {

    (Get-Content "C:\temp\scripts\users.txt")[2]

} else {

    Write-Output "ファイルはありません。"

}


# 実行結果

ビルゲイツ

 

 

 

また、範囲指定も可能です。

 

if (Test-Path "C:\temp\scripts\users.txt") {

    (Get-Content "C:\temp\scripts\users.txt")[2..4]

} else {

    Write-Output "ファイルはありません。"

}

# 実行結果

ビルゲイツ
キャプテンアメリカ
ハルク

 

 

 

ファイルの中身を検索

 

 

 

Where-Object コマンドレットを使った処理

 

 

ファイルの中から特定の文字列を検索して、コンソールに出力します。下記の画像はサンプルで作った適当なログファイルになりますが、このログの中からエラーの行だけ出力する事をやってみます。ファイルが存在する場合は、Get-Content でファイルの中身を $file_content に入れて、それを Where-Object で Like 検索しています。Where-Object で特定条件でデータを抽出することができます。

 

 

サンプルのログファイルの中身です。この中身から Where-Object で Like 検索します。

 

 

if (Test-Path "C:\temp\scripts\sample.log") {

    $file_content = (Get-Content "C:\temp\scripts\sample.log")
    $file_content | Where-Object { $_ -like "*ERROR*" }

} else {

    Write-Output "ファイルはありません。"

}


# 実行結果

#ERROR: This is a an error
#ERROR: This is a an error
#ERROR: This is a an error

 

 

 

Select-String コマンドレットを使った処理

 

 

Select-String コマンドレットはファイルからテキストを検索します。先ほどのログファイルを使っています。ファイルが存在する場合は、Get-Content でファイルの中身を $file_content に入れて、Select-String で。Where-Object で特定条件でデータを抽出することができます。オプションで指定している -Pattern は検索するテキストを文字列で指定しています。詳細は @IT の記事にありますのでリンクを貼っておきます。

 

 

【 Select-String 】コマンドレット――ファイルからテキスト(文字列)を検索する | @IT

 

 

 


if (Test-Path "C:\temp\scripts\sample.log") {

    $file_content = (Get-Content "C:\temp\scripts\sample.log")
    $file_content | Select-String -Pattern "Error"

} else {

    Write-Output "ファイルはありません。"

}


# 実行結果

#ERROR: This is a an error
#ERROR: This is a an error
#ERROR: This is a an error

 

 

 

また、以下のように -CaseSensitive オプションを使って、大文字小文字を区別して該当するテキストをコンソールに表示する事もできます。Linux でいうところの grep コマンドのようなものでしょうかね。

 

if (Test-Path "C:\temp\scripts\sample.log") {

    $file_content = (Get-Content "C:\temp\scripts\sample.log")
    "ERROR", "Error" | Select-String -Pattern "ERROR" -CaseSensitive

} else {

    Write-Output "ファイルはありません。"

}


# 実行結果

ERROR

 

 

 

エラーハンドリングを使った処理

 

 

try-catch を使って、エラーハンドリングをします。

 

 

  1. try を始めます。
  2. ファイルの場所を $file に代入します。
  3. Test-Path コマンドレットで $file が存在するか確認します。
    • 存在する場合は $file の中身を $file_content に代入し、Select-String で “Error” を含むテキストを表示します。
      • -ErrorAction でエラーが発生した場合に処理を中止します。
    • 存在しない場合は 「ファイルはありません」と表示します。
  4. try できなければ catch でエラーを表示します。

 

 

try {

    $file = "C:\temp\scripts\sample.log"

    if (Test-Path $file) {

         $file_content = (Get-Content $file)
         $file_content | Select-String -Pattern "Error" -ErrorAction stop -ErrorVariable "err"

    } else {

        Write-Output "ファイルはありません。"

    }

} catch {

    Write-Output "不明なエラーです。エラー: $err"

}

 

 

 

ファイルに書き込む

 

 

以下のように、テキストファイルにテキストを書き込みます。

 

 

 

Out-File コマンドレットを使ってテキストファイルに書き込みます。オプション有無で動作が異なりますので注意が必要です。

 

 

  • オプション無しだとファイルに対して上書き
  • -Append オプション有りでファイルに対して追記

 

 

以下のスクリプトでは、ファイルの場所を $file に代入して、$file が存在すれば、Write-Output で日時とテキストをファイルに追記します。

 

$file = "C:\temp\scripts\sample.log"

if (Test-Path $file) {

    Write-Output "$(Get-Date): This is a text" | Out-File -FilePath $file -Append

} else {

    Write-Output "ファイルはありません。"

}

 

 

 

以上になります。いかがでしょうか。

 

 

テキストファイルの操作は処理結果をログファイルに残すとかで使えそうですね。

 

 

では最後までお読みいただきありがとうございました!