LoginSignup
5
7

More than 5 years have passed since last update.

ファイルサーバ上に置いてある古くて大きいファイルを見つける(バッチとPowerShellでの比較)

Last updated at Posted at 2015-01-27

きっかけ

日次で古くて大きめなファイルをリストアップしたいと思い、はじめはバッチで書いていたのですが、
1. 作成したコードがけっこうな長さになってしまう
2. バッチの実行スピードが思ったよりも速くない

ということで比較のためにPowerShellでも同じ処理を書いてみました。

なかなか面白い結果が出たので内容を以下にまとめてみます。

処理の概要

指定したディレクトリ(例ではN:\share配下)の中から、ファイルサイズが10メガバイト以上かつ更新日が2年以上前のものをリストアップし、結果をテキストファイルに出力する1

環境

Windows Server 2008R2
PowerShellのバージョンは2.0
処理対象のディレクトリはファイルサーバー上にあり、約1,000個のファイルが格納されています

コード

listup.bat
@echo off

rem カッコ内でsetを遅延反映させるためのオプション
setlocal  ENABLEDELAYEDEXPANSION

rem 以降、遅延反映させたい変数には$hoge$のかわりに!hoge!と記述

set target_folder=N:\share

set YYYY=%date:~-10,4%
set MM=%date:~-5,2%
set DD=%date:~-2,2%
set /a YYYY=YYYY-2

rem 出力ファイル名(固定名+現在日時.lst)
set output=%~dp0\files_bat_%time:~-11,2%%time:~-8,2%%time:~-5,2%.lst

FOR /F "usebackq delims=" %%F in (`dir /B /S %target_folder%\*.*`) do if %%~zF GTR 10000000 (

  set upd_time=%%~tF
  set minutes=!upd_time:~-5,2!
  set seconds=!upd_time:~-2,2!

  rem 更新日付の比較
  if "!upd_time!" GTR "%YYYY%/%MM%/%DD% !minutes!:!seconds!" (
    rem 新しいファイル
  ) else (
    rem 古いファイル
    echo %%F>> %output%
  )
)

listup.ps1
$targetPath = "N:\share"

$scriptPath = Split-Path $script:myInvocation.MyCommand.path -parent

$output = $scriptPath\files_ps1_$time.lst

$time = Get-Date -Format "HHmmss"

$a = Get-ChildItem -recurse $targetPath
foreach($x in $a)
    {
        $y = ((Get-Date) - $x.LastWriteTime).Days
        if ($y -gt 730 -and $x.PsISContainer -ne $True -and $x.Length -gt 10000000)
            {echo $x.fullname | Out-File -filePath $output -Append -encoding Default}
    }

※ 厳密にいうと2年前(バッチの処理)と730日前(PowerShellの処理)は違うんじゃないすかと言われそうですが、はい、そのとおりです。。。ざっくり2年間前以前を抽出したかったのでこのようになっています。

処理時間計測結果

バッチ PowerShell
一回目 15.95秒 2.02秒
二回目 15.85秒 2.04秒
三回目 16.20秒 2.06秒

考察

なぜこれほど実行時間に差が出たのか気になりました。
I/Oがバッチの方が多いのかな???と思ってtaskmgr.exeから調べてみましたが

バッチ PowerShell
I/O Read 953,600 byte 987,525 byte
I/O Write 13,802 byte 21,918 byte

とほぼ同じくらい・・・
ふむ。

バッチの処理をあらためて見ると、変数に格納したり計算したりしているのでここらが足をひっぱっているのではないかと推測します。冗長なコード⇒それに伴う演算処理量アップな気がします。

とは言え、今回の場合は「ファイルサイズが大きくて古いファイルを見つけるコマンド」にピンポイントで該当するものがなく、「dirコマンド」結果を一個一個「for」の中で処理していますので、どストライクなコマンドがあれば、処理時間はあまり変わらないのではないかとも思います。

今回の結論

バッチ PowerShell
コードがやや冗長 コードは簡素
処理が遅い 処理はまあまあ速い2

  1. さらにその背景を記述すると、ファイルサーバ上に今後はほぼ使わなさそうなファイル(過去のバグ調査で使ったデバッグログとか)を置いているグループの人たちに、自動で注意を出して、何日か経過すると自動的にzip圧縮するような仕組みを考えていました 

  2. PowerShellがver.1のときは最初の起動がくっそ遅かったので隔世の感があります 

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7