この記事は以下のシリーズの19番目の記事です。
この記事でやること
この記事では、PowerShellで取得した一覧を見やすく整形する方法を整理します。
前回の記事では、Where-Object を使って条件に合うファイルだけを抽出しました。
今回は、その結果を次のように整えます。
| やりたいこと | 使うコマンド |
|---|---|
| 必要な項目だけ表示する | Select-Object |
| 更新日時やサイズで並べる | Sort-Object |
| 拡張子やフォルダごとに集計する | Group-Object |
PowerShellでは、次のような流れがよく使われます。
Get-ChildItem -File -Recurse |
Where-Object { $_.Extension -eq ".log" } |
Sort-Object LastWriteTime -Descending |
Select-Object Name, FullName, LastWriteTime
考え方は、次の通りです。
集める → 絞る → 並べる → 必要な項目だけ表示する
まず結論
ファイル一覧を整形する基本形は、次の通りです。
Get-ChildItem -File -Recurse |
Select-Object Name, FullName, Extension, Length, LastWriteTime
更新日時の新しい順に並べるなら、次のようにします。
Get-ChildItem -File -Recurse |
Sort-Object LastWriteTime -Descending |
Select-Object Name, FullName, LastWriteTime
拡張子ごとに件数を集計するなら、次のようにします。
Get-ChildItem -File -Recurse |
Group-Object Extension |
Select-Object Name, Count
実務では、この3つを使えるだけで、ファイル調査・ログ調査・共有フォルダ整理がかなり楽になります。
検証用フォルダを作る
まず、検証用フォルダを作成します。
New-Item -ItemType Directory -Path "C:\work\ps-format-test" -Force
Set-Location "C:\work\ps-format-test"
検証用ファイルを作成します。
Set-Content -Path ".\sample1.txt" -Value "text file 1"
Set-Content -Path ".\sample2.txt" -Value "text file 2"
Set-Content -Path ".\app.log" -Value "application log"
Set-Content -Path ".\error.log" -Value "error log"
Set-Content -Path ".\data.csv" -Value "id,name"
サブフォルダも作成します。
New-Item -ItemType Directory -Path ".\sub" -Force
Set-Content -Path ".\sub\subsample.txt" -Value "sub folder text"
Set-Content -Path ".\sub\sublog.log" -Value "sub folder log"
Set-Content -Path ".\sub\report.csv" -Value "report"
確認します。
Get-ChildItem -Recurse
Select-Objectで必要な項目だけ取り出す
Select-Object は、必要な項目だけを取り出すコマンドです。
まず、普通にファイル一覧を取得します。
Get-ChildItem -File -Recurse
この結果には、ファイル名、サイズ、更新日時、属性など、さまざまな情報が含まれています。
必要な項目だけを表示するには、Select-Object を使います。
Get-ChildItem -File -Recurse |
Select-Object Name, FullName, Extension, Length, LastWriteTime
よく使う項目は次の通りです。
| 項目 | 内容 |
|---|---|
| Name | ファイル名 |
| FullName | フルパス |
| DirectoryName | 親フォルダ |
| Extension | 拡張子 |
| Length | ファイルサイズ |
| CreationTime | 作成日時 |
| LastWriteTime | 更新日時 |
ファイル調査では、まずこの形を覚えると便利です。
Get-ChildItem -File -Recurse |
Select-Object Name, FullName, Length, LastWriteTime
表示する項目の順番を変える
Select-Object では、指定した順番で項目が表示されます。
Get-ChildItem -File -Recurse |
Select-Object LastWriteTime, Name, FullName
この場合、更新日時、ファイル名、フルパスの順に表示されます。
CSVに出力するときも、この順番が列の順番になります。
Get-ChildItem -File -Recurse |
Select-Object LastWriteTime, Name, FullName |
Export-Csv -Path ".\file_list.csv" -NoTypeInformation -Encoding UTF8
Excelで見ることを前提にするなら、列の順番を意識しておくと見やすくなります。
計算した列を追加する
Length はバイト単位です。
そのままだと分かりにくいので、KBやMBに変換した列を追加できます。
Get-ChildItem -File -Recurse |
Select-Object Name,
FullName,
@{Name="SizeKB"; Expression={[math]::Round($_.Length / 1KB, 2)}},
LastWriteTime
この部分で、SizeKB という列を作っています。
@{Name="SizeKB"; Expression={[math]::Round($_.Length / 1KB, 2)}}
MBで表示する場合は、次のようにします。
Get-ChildItem -File -Recurse |
Select-Object Name,
FullName,
@{Name="SizeMB"; Expression={[math]::Round($_.Length / 1MB, 2)}},
LastWriteTime
共有フォルダ調査では、Length よりも SizeMB の方が見やすいことが多いです。
Sort-Objectで並べ替える
Sort-Object は、一覧を並べ替えるコマンドです。
ファイル名順に並べる場合です。
Get-ChildItem -File -Recurse |
Sort-Object Name |
Select-Object Name, FullName
更新日時の古い順に並べる場合です。
Get-ChildItem -File -Recurse |
Sort-Object LastWriteTime |
Select-Object Name, FullName, LastWriteTime
更新日時の新しい順に並べる場合は、-Descending を付けます。
Get-ChildItem -File -Recurse |
Sort-Object LastWriteTime -Descending |
Select-Object Name, FullName, LastWriteTime
ファイルサイズの大きい順に並べる場合です。
Get-ChildItem -File -Recurse |
Sort-Object Length -Descending |
Select-Object Name,
FullName,
@{Name="SizeKB"; Expression={[math]::Round($_.Length / 1KB, 2)}}
大きなファイルを探したいときは、この形が便利です。
複数条件で並べ替える
Sort-Object は、複数の項目で並べ替えることもできます。
拡張子順に並べ、その中でファイル名順に並べる例です。
Get-ChildItem -File -Recurse |
Sort-Object Extension, Name |
Select-Object Extension, Name, FullName
拡張子順に並べ、その中で更新日時の新しい順に並べたい場合は、少し書き方を変えます。
Get-ChildItem -File -Recurse |
Sort-Object Extension, @{Expression="LastWriteTime"; Descending=$true} |
Select-Object Extension, Name, LastWriteTime, FullName
実務では、まず単純な並べ替えから使えば十分です。
よく使うのは次の3つです。
Sort-Object Name
Sort-Object LastWriteTime -Descending
Sort-Object Length -Descending
Group-Objectで件数を集計する
Group-Object は、同じ値ごとにグループ化して集計するコマンドです。
拡張子ごとに件数を集計します。
Get-ChildItem -File -Recurse |
Group-Object Extension
見やすくするなら、Select-Object で Name と Count だけ取り出します。
Get-ChildItem -File -Recurse |
Group-Object Extension |
Select-Object Name, Count
出力イメージは次のようになります。
Name Count
---- -----
.csv 2
.log 3
.txt 3
これは、共有フォルダの中にどの種類のファイルが多いかを調べるときに便利です。
フォルダごとに件数を集計する
親フォルダごとのファイル件数を集計する場合です。
Get-ChildItem -File -Recurse |
Group-Object DirectoryName |
Select-Object Name, Count
Name にはフォルダパスが入ります。
Count には、そのフォルダにあるファイル数が入ります。
フォルダごとのファイル数を調査したい場合に使えます。
拡張子ごとの合計サイズを出す
Group-Object でグループ化したあと、合計サイズを出すこともできます。
Get-ChildItem -File -Recurse |
Group-Object Extension |
Select-Object Name,
Count,
@{Name="TotalSizeMB"; Expression={[math]::Round(($_.Group | Measure-Object Length -Sum).Sum / 1MB, 2)}}
ここでは、拡張子ごとに次の情報を出しています。
| 項目 | 内容 |
|---|---|
| Name | 拡張子 |
| Count | ファイル数 |
| TotalSizeMB | 合計サイズMB |
Group-Object の結果には、Group というプロパティがあります。
その中に、同じグループに属するファイルの一覧が入っています。
$_.Group
その Group に対して Measure-Object Length -Sum を使い、サイズを合計しています。
Measure-Objectで合計や平均を出す
合計サイズだけを見たい場合は、Measure-Object を使います。
Get-ChildItem -File -Recurse |
Measure-Object Length -Sum
ファイル数、合計、平均などを見たい場合です。
Get-ChildItem -File -Recurse |
Measure-Object Length -Sum -Average -Maximum -Minimum
ファイルサイズの合計をMBで見やすくするなら、次のようにします。
$result = Get-ChildItem -File -Recurse |
Measure-Object Length -Sum
[math]::Round($result.Sum / 1MB, 2)
Group-Object と Measure-Object を組み合わせると、拡張子別・フォルダ別の容量調査に使えます。
条件抽出してから整形する
前回の Where-Object と組み合わせると、条件に合うものだけを整形できます。
30日以上更新されていないファイルを、新しい順に並べて表示します。
Get-ChildItem -File -Recurse |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
Sort-Object LastWriteTime -Descending |
Select-Object Name, FullName, LastWriteTime
10MB以上のファイルを、大きい順に並べて表示します。
Get-ChildItem -File -Recurse |
Where-Object { $_.Length -ge 10MB } |
Sort-Object Length -Descending |
Select-Object Name,
FullName,
@{Name="SizeMB"; Expression={[math]::Round($_.Length / 1MB, 2)}},
LastWriteTime
.log ファイルだけを拡張子ごとに集計する例です。
この場合は拡張子が同じなので、あまり意味はありませんが、流れの例としては次のようになります。
Get-ChildItem -File -Recurse |
Where-Object { $_.Extension -eq ".log" } |
Group-Object Extension |
Select-Object Name, Count
CSVに出力する
整形した一覧は、CSVに出力すると実務で使いやすくなります。
ファイル一覧をサイズの大きい順にCSV出力する例です。
Get-ChildItem -File -Recurse |
Sort-Object Length -Descending |
Select-Object Name,
FullName,
Extension,
@{Name="SizeMB"; Expression={[math]::Round($_.Length / 1MB, 2)}},
LastWriteTime |
Export-Csv -Path ".\file_size_list.csv" -NoTypeInformation -Encoding UTF8
拡張子ごとの件数と合計サイズをCSVに出力する例です。
Get-ChildItem -File -Recurse |
Group-Object Extension |
Select-Object Name,
Count,
@{Name="TotalSizeMB"; Expression={[math]::Round(($_.Group | Measure-Object Length -Sum).Sum / 1MB, 2)}} |
Export-Csv -Path ".\extension_summary.csv" -NoTypeInformation -Encoding UTF8
Excelで開く前提なら、環境に応じて utf8BOM や Default を検討します。
Export-Csv -Path ".\extension_summary.csv" -NoTypeInformation -Encoding utf8BOM
実務で使いやすいテンプレート1:大きいファイル一覧
共有フォルダから大きいファイルを探すテンプレートです。
$targetDir = Join-Path $PSScriptRoot "target"
$outputDir = Join-Path $PSScriptRoot "output"
New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
$today = Get-Date -Format "yyyyMMdd"
$outputPath = Join-Path $outputDir "large_files_$today.csv"
Get-ChildItem -Path $targetDir -File -Recurse |
Where-Object { $_.Length -ge 10MB } |
Sort-Object Length -Descending |
Select-Object Name,
FullName,
Extension,
@{Name="SizeMB"; Expression={[math]::Round($_.Length / 1MB, 2)}},
LastWriteTime |
Export-Csv -Path $outputPath -NoTypeInformation -Encoding UTF8
このテンプレートでは、次の処理をしています。
target配下のファイルを集める
10MB以上に絞る
サイズの大きい順に並べる
必要な項目だけ選ぶ
CSVに出力する
実務で使いやすいテンプレート2:拡張子別集計
共有フォルダ内のファイルを拡張子別に集計するテンプレートです。
$targetDir = Join-Path $PSScriptRoot "target"
$outputDir = Join-Path $PSScriptRoot "output"
New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
$today = Get-Date -Format "yyyyMMdd"
$outputPath = Join-Path $outputDir "extension_summary_$today.csv"
Get-ChildItem -Path $targetDir -File -Recurse |
Group-Object Extension |
Sort-Object Count -Descending |
Select-Object Name,
Count,
@{Name="TotalSizeMB"; Expression={[math]::Round(($_.Group | Measure-Object Length -Sum).Sum / 1MB, 2)}} |
Export-Csv -Path $outputPath -NoTypeInformation -Encoding UTF8
このテンプレートでは、次のような集計ができます。
.txt が何件あるか
.log が何件あるか
.csv が何件あるか
拡張子ごとの合計サイズはいくらか
共有フォルダの棚卸しや、不要ファイル調査の入口として使いやすいです。
よくあるつまずき
Select-Objectで存在しない項目を指定している
たとえば、Filename という項目は通常ありません。
Get-ChildItem -File |
Select-Object Filename
ファイル名は Name を使います。
Get-ChildItem -File |
Select-Object Name
どんな項目があるか見たい場合は、Get-Member を使います。
Get-ChildItem -File |
Get-Member
Sort-ObjectのDescendingを忘れる
サイズの大きい順にしたい場合は、-Descending が必要です。
Sort-Object Length -Descending
-Descending がないと、小さい順になります。
Group-Objectの結果をそのままCSVに出して見にくい
Group-Object の結果には、Group という詳細情報も含まれます。
そのままCSVに出すと見にくいことがあります。
Get-ChildItem -File -Recurse |
Group-Object Extension |
Export-Csv ".\summary.csv" -NoTypeInformation -Encoding UTF8
必要な項目だけ選びます。
Get-ChildItem -File -Recurse |
Group-Object Extension |
Select-Object Name, Count |
Export-Csv ".\summary.csv" -NoTypeInformation -Encoding UTF8
Lengthがバイト単位で分かりにくい
Length はバイト単位です。
MBに変換すると見やすくなります。
@{Name="SizeMB"; Expression={[math]::Round($_.Length / 1MB, 2)}}
いきなり削除処理につなげる
一覧整形に慣れると、抽出した結果を削除や移動につなげたくなります。
ただし、削除処理は必ず確認してから実行します。
Get-ChildItem -File -Recurse |
Where-Object { $_.Extension -eq ".log" } |
Remove-Item -WhatIf
まず -WhatIf で対象を確認するのがおすすめです。
まとめ
この記事では、PowerShellで一覧を整形するための Select-Object / Sort-Object / Group-Object を整理しました。
基本的な役割は次の通りです。
| コマンド | 役割 |
|---|---|
| Select-Object | 必要な項目だけ選ぶ |
| Sort-Object | 並べ替える |
| Group-Object | グループ化して件数を数える |
| Measure-Object | 合計・平均・最大・最小を出す |
実務でよく使う形は、次の通りです。
Get-ChildItem -File -Recurse |
Where-Object { 条件 } |
Sort-Object LastWriteTime -Descending |
Select-Object Name, FullName, LastWriteTime |
Export-Csv -Path ".\result.csv" -NoTypeInformation -Encoding UTF8
拡張子別に集計するなら、次の形です。
Get-ChildItem -File -Recurse |
Group-Object Extension |
Select-Object Name, Count
PowerShellで一覧を扱うときは、次の流れで考えると分かりやすいです。
集める
絞る
並べる
選ぶ
集計する
出力する
Select-Object、Sort-Object、Group-Object を使えるようになると、ファイル一覧をただ表示するだけでなく、調査資料や棚卸し資料として使える形に整えられます。