【Windows】Windowsの標準機能でzipファイルの一覧を取得して特定の拡張子を持ったファイルを格納しているzipファイルを特定する

お久しぶりです。表題の通りです。なんとも読みにくい記事です。ごめんね。

概要

  • ドライブ内のzipファイルの一覧を取得する
  • 取得した一覧をもとに、特定の拡張子のファイルを格納しているzipファイルを特定する

コード

zipファイルの一覧を取得する

コマンドプロンプト用のバッチファイル(.bat)

@echo off
setlocal enabledelayedexpansion

type nul > listup_zipfile_output.txt
set /a founds=0

echo processing...
echo zip found : !founds!

for /r %%F in (*.*) do (
    if /i "%%~xF"==".zip"    (
        cls
        echo processing...
        echo zip found : !founds!
        echo %%F >> listup_zipfile_output.txt
        set /a founds=!founds!+1
    )
)
echo process done.press any key to exit.
pause > nul
exit

取得した一覧から特定の拡張子のファイルを格納しているzipのファイルパスを表示する

PowerShell用のバッチファイル(.ps1)

add-type -assemblyname system.io.compression.filesystem
[IO.Directory]::SetCurrentDirectory((Get-Location).Path)
$current_directory = [IO.Directory]::GetCurrentDirectory()
$target_zipfile_list = "listup_zipfile_output.txt"
$target_extensions = @(".exe", ".mp3")
echo "Current Directory`t-> $current_directory"
echo "Target Zipfilelist`t-> $target_zipfile_list"
echo "Target Extentsions`t-> $target_extensions"

foreach ($zip_filepath in Get-Content $target_zipfile_list) {
    # ZIPファイルの持つ内容のコレクション
    $zipfilecollection = [io.compression.zipfile]::openread($zip_filepath).entries
    foreach($file in $zipfilecollection){
        $isZipHasTargetExtension = $false
        $file_extention = [System.IO.Path]::GetExtension($file.Name);
        foreach($extension in $target_extensions){
            if($file_extention -eq $extension){
                echo $zip_filepath
                $isZipHasTargetExtension = $true
                break
            }
        }
        if($isZipHasTargetExtension -eq $true){
            break
        }
    }
}

コピペして使う人向けの使い方

  1. zipファイルの一覧を取得したいドライブの直下に.batと.ps1の拡張子で保存した上記のバッチファイルを配置する
  2. .ps1の$target_extensions = @(".exe", ".mp3")の行の.exeやら.mp3の中身を探したい拡張子で置き換える
  3. .bat→.ps1の順番で実行(手を加えないならps1はPowerShell上で実行しましょう)
  4. おわり ちなみにファイルの拡張子の大文字小文字の区別はつけないと思います。

中身の話

add-type -assemblyname system.io.compression.filesystem

zipファイルを展開したりするアセンブリのインクルード宣言みたいなやつらしいっすよ(適当)

[IO.Directory]::SetCurrentDirectory((Get-Location).Path)

最初これ書かなくてつまづいた。.NET Frameworkの機能を使う場合はこれでカレントディレクトリを移動してあげないとダメみたい。

$zipfilecollection = [io.compression.zipfile]::openread($zip_filepath).entries

zipファイルのフルパスからzipファイルをオープンして、ファイル内容の一覧を取得するとこ。ちなみになんだけどzipファイルは構造上、パスワード付きzipにしてもファイル名の一覧は見えちゃうのでファイル名は人に見せても大丈夫な名前にしておこうね。

$file_extention = [System.IO.Path]::GetExtension($file.Name);

ファイル名の形式だとGetExtension()を使って拡張子だけパースできるんだって。便利だねぇ。

if($file_extention -eq $extension){

-eqで比較すると大文字小文字の区別なしで比較するみたい。厳密な比較は-ceq、他にもワイルドカードで比較する-likeとかあるので気になったらググってください。

余談

zipファイルの中身を見るならUnzipとかでいいじゃんと思ってたけどデフォルトだとWindowsに入ってないんだよね。なんやかんやあってUnzipも導入するのが面倒な環境だとどうしたらいいんだろうってなってたので調べた。
PowerShellってそういえば触ったことが無かったな・・・