none
powershellプロパティ抽出について(条件付き)

    質問

  • Get-ChildItem | Where-Object {$_.Length -ge 10MB} | Select-Object @{Name='LastWriteTime';Expression={$_.LastWriteTime.ToString("yyyy/MM/dd")}}, @{Name='Length';Expression={$_.Length / 1MB}}, FullName | Export-Csv out.csv -NoTypeInformation -Encoding Default

    ↑参考にされていた抱いた式です。(フォルダの中の10MB以上のファイルの容量・最終更新日・フルパスを抽出)

    これを改良したいのです。

    動画ファイルの場合は追加で下記情報を横に取得したいのです。

    抽出したいプロパティ(長さ:27、幅285:、高さ:283、フレーム率:284、データ速度:282)

    最終的にはこのようにCSVファイルに出力したいのです。
    可能であれば教えて頂けませんか?

    よろしくお願い致します。



    2018年1月10日 9:25

すべての返信

  • Get-ChildItemコマンドで取得するFileInfoオブジェクトには、動画ファイルの長さやフレーム率といったプロパティは含まれていないため、他の方法で取得する必要があります。といっても自前で動画ファイルを解析するのは困難なので、以下のようにエクスプローラーの機能を利用するCOMオブジェクト(Shell.Application)のGetDatailsOfメソッドを用いる方法が考えられます。

    なお、データ速度:282等の属性名と番号の対応は、環境によって変動するので、以下のように事前に対応テーブルを作っておくのが良いと思われます。また、当方環境(Win10)では動画サイズを表す属性は「幅」と「高さ」ではなく、「フレーム幅」と「フレーム高」という属性名だったので、変更してあります。

    # 対象フォルダパス
    $path = "D:\movies"
    
    # 取得する属性名
    $attributeNames = @("長さ", "フレーム幅", "フレーム高", "フレーム率", "データ速度") 
    
    $shell = New-Object -ComObject Shell.Application 
    $folder = $shell.Namespace($path)  
    $attributeTable = @{}
    
    # 連想配列(key=属性名、value=属性番号)を作成する。
    0..500 | 
        foreach {
            $attributeName = $folder.GetDetailsOf($null, $_)
            if($attributeName -in $attributeNames)
            {
                $attributeTable[$attributeName] = $_
            }
        }
    
    # ファイルリストを作成する。
    $files = foreach($item in $folder.Items() | where{-not $_.IsFolder})
        {
            $file = Get-Item $item.Path
            # 指定した属性をFileInfoオブジェクトのプロパティとして追加。
            $attributeNames | foreach {
                $value = $folder.GetDetailsOf($item, $attributeTable[$_]) -replace ([char]8206) # LEFT-TO-RIGHT MARK除去
                $file | Add-Member -MemberType NoteProperty -Name $_ -Value $value 
            }
            $file
        }
    
    # 出力するプロパティのリストを作成する。
    $properties =  
        @{Name='LastWriteTime'; Expression={$_.LastWriteTime.ToString("yyyy/MM/dd")}},
        @{Name='Length'; Expression={"$([Math]::Floor($_.Length / 1MB)) MB"}},
        "FullName" +
        $attributeNames
    
    # ファイルリストから指定のプロパティ値のみ取得し、CSV出力する。        
    $files | 
        Where-Object Length -ge 10MB |
        Select-Object $properties |
        Export-Csv out.csv -NoTypeInformation -Encoding Default
    これでもだいぶめんどくさいですが…。

    2018年1月11日 23:47
    モデレータ
  • ご回答ありがとうございます!

    このプログラムってバージョンによってエラーが出たりしますかね?

    追加で質問なのですが、任意のセルに出力することってできるんですか?

    あと、CSVファイルの出力では無く直接既存のエクセルに書き出しすることが可能なのでしょうか?


    • 編集済み hitton 2018年1月13日 4:19
    2018年1月13日 4:16
  • このプログラムってバージョンによってエラーが出たりしますかね?

    PowerShell 3.0以降ではエラーを出さず動作すると思います。当方はPowerShell 5.1/Windows 10の環境で動作確認しました。

    追加で質問なのですが、任意のセルに出力することってできるんですか?

    ご質問の意味を掴みかねるのですが、具体的にどういうことでしょうか?

    あと、CSVファイルの出力では無く直接既存のエクセルに書き出しすることが可能なのでしょうか?

    .xlsxファイルなどに、ということでしょうか?

    PCにExcelがインストールされている必要がありますが、COMオブジェクト(Excel.Application)経由で可能かと思います。このキーワードで検索いただければ例も出て来ると思います。


    2018年1月13日 5:24
    モデレータ
  • powershell 2.0 /win7 で実行した所

    if($attributeName -in $attributeNames) の部分で「-in 」「$attributeNames」使用できないと出ました。

    質問1

    例えば、動画ファイルのプロパティをセル「F1」からに出力したいのです。

    可能でしょうか?

    質問2

    既存のエクセルファイルに書き出す場合はどこでエクセルを開く宣言文など入れたらいいのか

    複雑でわからないのですが

    教えていただけますか?

    • 編集済み hitton 2018年1月13日 9:02
    2018年1月13日 8:57
  • チャブーンです。

    回答ではありません。

    質問者さんに対してですが、質問の内容や範囲について、多少考え直されてはいかがでしょうか?

    追加の質問ですが、質問者さんのPowerShellスキルに見合った内容なのでしょうか。ご自身の手に負えないので、他の方に全部を依存する、という質問は一般に「丸投げ」といいます。

    丸投げは、回答者に負担のかかる行為ですので、コミュニティへの質問としてはふさわしくありません。ご自身で内容を咀嚼してから、あらためてわからない内容を質問されてはどうでしょうか。

    老婆心ながら、したのようなコンテンツも読まれることをお奨めします。

    http://www.hyuki.com/writing/techask.html


    フォーラムは有償サポートとは異なる「コミュニティ」です。フォーラムでご質問頂くにあたっての注意点 をご一読のうえ、お楽しみください。

    2018年1月14日 5:02
  • > if($attributeName -in $attributeNames) の部分で「-in 」「$attributeNames」使用できないと出ました。

    PowerShell 2.0であれば、代わりに

    if($attributeNames -contains $attributeName) 

    とすることで動作するかと思います。

    また、Where-Object Length -ge 10MB はWhere-Object {$_.Length -ge 10MB}に置き換えてみてください。

    Excelに関係する部分は「PowerShell Excel.Application」などでネット検索していただいて、いったんコード化したうえで何か分からない部分があれば別途スレッドを立ててご質問いただければ幸いです。なお、PowerShell以外にVBAの知識も必要になってくると思います。
    2018年1月16日 6:25
    モデレータ