PowerShellでファイルの最終更新日時を取得した際に、Format-Tableで列を入れ替えてからExport-CsvでCSV出力しようとしたら想定外の結果になりました。
Export-CsvとFormat-Tableを併用した場合(失敗)
> Get-ChildItem * -Recurse -File -Include *.txt |
Select-Object Name, DirectoryName, LastWriteTime |
Sort-Object -Property @{ Expression = 'LastWriteTime'; Descending = $true }, Name |
Format-Table -Property LastWriteTIme, Name, DirectoryName |
Export-Csv -Encoding Default -Path C:\work\update-list.csv
結果
#TYPE Microsoft.PowerShell.Commands.Internal.Format.FormatStartData "ClassId2e4f51ef21dd47e99d3c952918aff9cd","pageHeaderEntry","pageFooterEntry","autosizeInfo","shapeInfo","groupingEntry" "033ecb2bc07a4d43b5ef94ed5a35d280",,,,"Microsoft.PowerShell.Commands.Internal.Format.TableHeaderInfo", "9e210fe47d09416682b841769c78b8a3",,,,, "27c87ef9bbda4f709f6b4002fa4af63c",,,,, "27c87ef9bbda4f709f6b4002fa4af63c",,,,, "27c87ef9bbda4f709f6b4002fa4af63c",,,,, "27c87ef9bbda4f709f6b4002fa4af63c",,,,, 以下、割愛
Export-CsvとFormat-Tableを併用しない場合(成功)
> Get-ChildItem * -Recurse -File -Include *.txt |
Select-Object Name, DirectoryName, LastWriteTime |
Sort-Object -Property @{ Expression = 'LastWriteTime'; Descending = $true }, Name |
Export-Csv -Encoding Default -Path C:\work\update-list.csv
説明(公式ページの転載)
これは公式のExport-Csvコマンドレットのページに記載あります。(以下抜粋)
パイプライン内の Format コマンドレットによって予期しない結果が作成される
この例では、パイプライン内で format コマンドレットを使用しないことが重要である理由を示します。 予期しない出力が受信されたら、パイプライン構文のトラブルシューティングを行います。
Get-Date | Select-Object -Property DateTime, Day, DayOfWeek, DayOfYear | Export-Csv -Path .\DateTime.csv -NoTypeInformation Get-Content -Path .\DateTime.csv "DateTime","Day","DayOfWeek","DayOfYear" "Wednesday, January 2, 2019 14:59:34","2","Wednesday","2" Get-Date | Format-Table -Property DateTime, Day, DayOfWeek, DayOfYear | Export-Csv -Path .\FTDateTime.csv -NoTypeInformation Get-Content -Path .\FTDateTime.csv "ClassId2e4f51ef21dd47e99d3c952918aff9cd","pageHeaderEntry","pageFooterEntry","autosizeInfo", ... "033ecb2bc07a4d43b5ef94ed5a35d280",,,,"Microsoft.PowerShell.Commands.Internal.Format. ... "9e210fe47d09416682b841769c78b8a3",,,,, "27c87ef9bbda4f709f6b4002fa4af63c",,,,, "4ec4f0187cb04f4cb6973460dfe252df",,,,, "cf522b78d86c486691226b40aa69e95c",,,,,
コマンドレットは Get-Date DateTime オブジェクトを取得します。 オブジェクトは、パイプラインからコマンドレットに Select-Object 送信されます。 Select-Objectでは、Property パラメーターを使用してオブジェクト プロパティのサブセットを選択します。 オブジェクトは、パイプラインからコマンドレットに Export-Csv 送信されます。 Export-Csv は、オブジェクトを CSV 形式に変換します。 Path パラメーターは、ファイルが現在のDateTime.csvディレクトリに保存されることを指定します。 NoTypeInformation パラメーターは、csv 出力から #TYPE 情報ヘッダーを削除します。PowerShell 6 では必要ありません。 このコマンドレットではGet-Content、Path パラメーターを使用して、現在のディレクトリにある CSV ファイルを表示します。
パイプライン内でコマンドレットを Format-Table 使用してプロパティを選択すると、予期しない結果が受信されます。 Format-Tableは、DateTime オブジェクトではなく、パイプラインの下にExport-Csvテーブル形式オブジェクトを送信します。 Export-Csv は、テーブル形式オブジェクトを一連の CSV 文字列に変換します。 このコマンドレットは Get-Content 、テーブル形式オブジェクトを含む CSV ファイルを表示します。