タイダログ

もっと怠けますか? (y/n)

PowerShell でフォルダサイズの一覧を取得する:3.0 REDO.

CSV があれば、(コンソールを閉じても)全部やり直せる。

2021/06/20 CSV出力した際にフォルダひとつ分の結果しか出力できなかった件について、コードを修正しました。

これまで、Windows PowerShell でフォルダサイズの一覧を取得する方法を紹介してきました。取得したデータを変数に格納してソートすれば、容量を食っているフォルダを特定できます。

ですが、コンソール(PowerShell の画面)を右上の×や exit で閉じると変数の中身は消えます。まあ当然です。当然なのですが、うっかり閉じてしまうこともあります。うっかり exit することはないかもしれませんが、うっかり Alt+F4Alt+Space+C などすることはあります。あります。Alt+Space+X しようとしたときなんか特に。

ということで、フォルダサイズの一覧を CSV ファイルに保存して、コンソールを閉じた後でも利用できるようにしましょう。

この話の続きです。

taidalog.hatenablog.com

taidalog.hatenablog.com

CSV に出力して結果を保存する

PowerShellCSV 出力するには、Export-Csv コマンドレットを使うと便利です。出力したいデータをパイプライン (|) 等で渡すだけです。

one-liner

フォルダサイズの取得方法は前回と全く同じです。
https://taidalog.hatenablog.com/entry/2021/03/16/053000#コード

CSV への出力手順は、

  1. 保存先の CSV ファイルのパスを作る
  2. フォルダサイズの一覧を取得する
  3. Export-Csv で出力する

だけです。こうします↓。

$csvPath = Join-Path ([Environment]::GetFolderPath("MyDocuments")) "DirectorySizes$((Get-Date).ToString('yyyy-MM-dd_HH-mm-ss')).csv"; Get-ChildItem -Recurse -Directory | ForEach-Object {$childItems = @(Get-ChildItem -LiteralPath $_.FullName -File); [long]$totalLength = ($childItems | Measure-Object Length -Sum).Sum; [PSCustomObject]@{Length = $totalLength; LengthMB = [Math]::Round($totalLength / 1MB, 2); LengthGB = [Math]::Round($totalLength / 1GB, 2); Count = $childItems.Length; FullName = $_.FullName}} | Export-Csv -Path $csvPath -Encoding utf8 -Append -NoTypeInformation

最初の

$csvPath = Join-Path ([Environment]::GetFolderPath("MyDocuments")) "DirectorySizes$((Get-Date).ToString('yyyy-MM-dd_HH-mm-ss')).csv";

で保存先の CSV ファイルのパスを作っています。[Environment]::GetFolderPath("MyDocuments") がユーザーのドキュメントフォルダを表していますので、保存先はドキュメントフォルダで、ファイル名は DirectorySizes_<yyyy-MM-dd_HH-mm-ss 形式の日時>.csv です。

最後の

 | Export-Csv -Path $csvPath -Encoding utf8 -Append -NoTypeInformation

CSV 出力をしています。

-Append パラメータを忘れてはいけません。これがないと前のデータを新しいデータで上書きしてしまうので、結果的に最後のフォルダのサイズしか CSV ファイルに残りません。

function

function (Measure-Directory) のコードは、前回同様 Gist でご覧ください。開いたページでスクリプトをダウンロードできます。
get_the_list_of_directory_size.psm1 · GitHub

モジュールファイル (.psm1) の使い方はお調べください。Set-ExecutionPolicyImport-Module ができれば OK です。

こちらの出力手順や保存先、ファイル名も one-liner と同じです。

$csvFilePrefix = 'DirectorySizes_'
$datetimeFormat = 'yyyy-MM-dd_HH-mm-ss'
$csvExtension = '.csv'
$csvPath = Join-Path ([Environment]::GetFolderPath("MyDocuments")) "$($csvFilePrefix)$((Get-Date).ToString($datetimeFormat))$($csvExtension)"

Get-ChildItem -Recurse -Directory | Measure-Directory | Export-Csv -Path $csvPath -Encoding utf8 -Append -NoTypeInformation

CSV のデータを変数に格納して再利用する

ここまでの手順で結果を CSV ファイルに保存できました。今度は、PowerShell で再び操作できるようにデータを変数に格納しましょう。CSV ファイルからの取り込みは Import-Csv コマンドレットです。ソートはそのまま Sort-Object コマンドレットです。

$csvPath = 'CSV ファイルへのパス'
$importedDirectorySize = Import-Csv -Path $csvPath -Encoding utf8
$importedDirectorySize | Sort-Object -Property Length -Descending | Format-Table

結果はこの通り。

Length    LengthMB LengthGB Count FullName
------    -------- -------- ----- --------
998511    0.95     0        1     D:\Users\taidalog\history\translation\Traget text
9963      0.01     0        19    D:\Users\taidalog\Documents\notes
9963      0.01     0        19    D:\Users\taidalog\Documents\3.33
99425810  94.82    0.09     10    D:\Users\taidalog\Music\Media\Music\
993041493 947.04   0.92     23    D:\Users\taidalog\Downloads
988829    0.94     0        5     D:\Users\taidalog\history\maps
98804736  94.23    0.09     1     D:\Users\taidalog\Documents\Outlook Files
98778     0.09     0        7     D:\Users\taidalog\MeasureExcelFunction\test
9849      0.01     0        6     D:\Users\taidalog\BackupDiskData
9834      0.01     0        7     D:\Users\taidalog\Documents\source\repos\HIUC1\HIUC1\x64\Debug

あら? 並び順がおかしいのでは? 9963 が 99425810 の上に来ている。

君が何を言っているのか分かんないよ!

CSV の数字を数値に変換する

$importedDirectorySize の中身は、CSV からインポートした文字列です。そう、文字列です。Length プロパティも文字のままです。「数字」と「数値」の違いですね。

これを [long] でキャストします。

$importedDirectorySize | Sort-Object -Property {[long]$_.Length} -Descending | Format-Table
Length     LengthMB LengthGB Count FullName
------     -------- -------- ----- --------
9656763028 9209.41  8.99     121   D:\Users\taidalog\Music\Media\Applications
993041493  947.04   0.92     23    D:\Users\taidalog\Downloads
860611018  820.74   0.8      42    D:\Users\taidalog\Music\Media\Music\Bulfinch
694238574  662.08   0.65     40    D:\Users\taidalog\Music\Media\Videos
630599256  601.39   0.59     3     D:\Users\taidalog\Downloads\F_20170912
581483418  554.55   0.54     16    D:\Users\taidalog\Documents\SCAN MG6730\MY_BA01
581483418  554.55   0.54     16    D:\Users\taidalog\history\SCAN MG6730\MY_BA01
566058060  539.84   0.53     33    D:\Users\taidalog\history\school\h29
429769935  409.86   0.4      3     D:\Users\taidalog\history\University\Library Supporter
398568754  380.1    0.37     166   D:\Users\taidalog\Music\Media\Music\italian_basic_a

ふう。コンソール上は文字列のままですが、ソートの際には数値に変換できています。

Sort-Object コマンドレットの -Property パラメータはスクリプトブロックを指定できるので、{[long]$_.Length} でよいみたいです。

qiita.com

winscript.jp

Microsoft のドキュメントにもありました。

docs.microsoft.com

まとめ

落ちが思いつかないので14年くらい寝ます。

続編

こちらもぜひ。

taidalog.hatenablog.com

参考

更新履歴

  • one-linerExport-Csv-Append パラメータを追加 (2021/06/20)
  • one-linerExport-Csv-Append パラメータの説明を追加 (2021/06/20)
  • functionExport-Csv-Append パラメータを追加 (2021/06/20)
  • :3.0+1.0 へのリンクを追加 (2021/06/22)
  • 目次の下に「こちらもどうぞ」を追加 (2021/09/09)
  • 参考」を追加 (2021/09/09)
  • 更新履歴」を追加 (2021/09/09)