0

データベースからエクスポートされているファイルでいっぱいのディレクトリがあります。ファイルは、ファイル名の末尾にバージョンが追加されて毎日作成されます。

ファイル名の構文:DocumentNumber_DocumentName_Version.pdf

目標:Windowsバッチファイルを使用して、古いバージョンの新しいファイルを/oldフォルダーに移動します。過去24時間に新しいバージョンがない既存のファイルは無視されます。

DocumentNumberは可変長にすることができ、ダッシュを含めることができ、アンダースコアで終わるDocumentName:可変長にすることができ、ダッシュ、スペース、アンダースコアを含めることができ、時間の経過とともに変化する可能性がありますバージョンは常に最後にあり、アンダースコアで始まります。英数字です。英数字は常に増分します。

例1:異なるバージョンのファイル:ディレクトリには...があります。

D00003456_BTW-FW001_OPTB_A12.pdf
D00003456_BTW-FW001_OPTB_B9.pdf
D00003456_BTW-FW001_OPTB_C6.pdf
D00003456_BTW-FW001_OPTB_D2.pdf (new)

DocumentNumber is D00003456
DocumentName is BTW-FW001_OPTB
Version is either A12, B9, C6 or D2

** Would like to move all to old folder except D2

例2:DocumentNameはバージョンごとに変わる可能性があります:ディレクトリには...

DPP-456_BTW-FW001_OPTB_A1.pdf
DPP-456_BTW-FW001_OPTB_C45.pdf
DPP-456_NEW WIDGET_F6.pdf
DPP-456_NEWER WIDGET_Blue_W2.pdf (new)

DocumentNumber is DPP-456
DocumentName is BTW-FW001_OPTB, "NEW WIDGET" or "NEWER WIDGET_Blue"
Version is either A1, C45, F6 or W2

** Would like to move all to old folder except W2

例3:古いバージョンのみを移動してすべてのファイルの最新バージョンを保持する:ディレクトリには...

SD0001_I001_A1.pdf
SD0001_ClassyWidget_C45.pdf (new)
SD0034_WIDGET_F6.pdf
00000056_NEWER WIDGET_Gray_W2.pdf

DocumentNumber is SD0001, SD0034 and 00000056
DocumentName is I001, ClassyWidget, "WIDGET" or "NEWER WIDGET_Gray"
Version is either A1, C45, F6 or W2

** Would like to move SD001 all to old folder except C45, others (SD0034 and 00000056) would be ignored
4

1 に答える 1

0

このトピックを数回読んだ後、同じドキュメントのすべてのバージョンが同じドキュメント番号を持っているために識別されると結論付けました(複数の例を示して推測するのではなく、この点を述べる必要があります)。

以下のバッチファイルは問題を解決します。

@echo off
setlocal EnableDelayedExpansion
set prevName=
for %%a in (*.pdf) do (
   if not defined prevName (
      rem Initialize process with first name and DocumentNumber
      set prevName=%%a
      for /F "delims=_" %%b in ("%%a") do set prevNumber=%%b
   ) else (
      rem Check if next name have the same DocumentNumber
      set nextName=%%a
      for /F "delims=_" %%b in ("%%a") do set nextNumber=%%b
      if "!prevNumber!" equ "!nextNumber!" (
         rem Yes: Two versions of same file, move the older one
         ECHO move "!prevName!" "C:\dest\dir"
      ) else (
         rem No: Different files, update DocumentNumber
         set prevNumber=!nextNumber!
      )
      rem Anyway, previous name was processed
      set prevname=!nextName!
   )
)

ディスク上のファイル:

00000056_NEWER WIDGET_Gray_W2.pdf
D00003456_BTW-FW001_OPTB_A12.pdf
D00003456_BTW-FW001_OPTB_B9.pdf
D00003456_BTW-FW001_OPTB_C6.pdf
D00003456_BTW-FW001_OPTB_D2.pdf
DPP-456_BTW-FW001_OPTB_A1.pdf
DPP-456_BTW-FW001_OPTB_C45.pdf
DPP-456_NEW WIDGET_F6.pdf
DPP-456_NEWER WIDGET_Blue_W2.pdf
SD0001_ClassyWidget_C45.pdf
SD0001_I001_A1.pdf
SD0034_WIDGET_F6.pdf

プログラムの結果:

move "D00003456_BTW-FW001_OPTB_A12.pdf" "C:\dest\dir"
move "D00003456_BTW-FW001_OPTB_B9.pdf" "C:\dest\dir"
move "D00003456_BTW-FW001_OPTB_C6.pdf" "C:\dest\dir"
move "DPP-456_BTW-FW001_OPTB_A1.pdf" "C:\dest\dir"
move "DPP-456_BTW-FW001_OPTB_C45.pdf" "C:\dest\dir"
move "DPP-456_NEW WIDGET_F6.pdf" "C:\dest\dir"
move "SD0001_ClassyWidget_C45.pdf" "C:\dest\dir"

編集:新しいコメントへの回答

前にも言ったように、あなたの説明は明確ではないので、私はあなたの例に基づいて私の解決策を示しました。私の以前のコードは、Ex3のドキュメント番号SD0001という1つの場合を除いて、元の例で正しく機能します。ただし、この場合、ファイルI001とClassyWidgetを逆の順序でリストしました。。DIRコマンドとFORコマンドはどちらも、最初にClassyWidgetをリストし、次にI001をリストします。なぜあなたはそれらを逆転させたのですか?問題の説明を読むとき、私はそれを解決する方法に焦点を合わせます。OPによって与えられたデータが正しいか間違っているかをチェックするのではありません!このようにして、私のソリューションは古いバージョンとして最後にリストされたファイルを提供します(すべての例に示されているように)。

この新しい「詳細」は、各DocNumberの最後のバージョンを最初に識別するために、すべてのファイルを2回通過する必要があるため、まったく異なるソリューションにつながります。問題の説明で「DocumentNameにはアンダースコアを含めることができる」と述べましたが、示されているすべての例には1つのアンダースコアしか含まれていません。以下の新しいソリューションは、DocumentNameにアンダースコアが1つしかない場合、またはアンダースコアがない場合に、古いバージョンを正しく取得します。複数の下線が含まれている可能性がある場合は、「小さな」変更が必要です。

@echo off
setlocal EnableDelayedExpansion
rem First pass: get oldest version of each DocNumber
for %%a in (*.pdf) do (
   rem docNumber=First token (%%b), version=fourth (%%e) or third (%%d) token
   for /F "tokens=1-4 delims=_" %%b in ("%%~Na") do (
      set version=%%e
      if not defined version set version=%%d
      if "!version!" gtr "!oldestVersion[%%b]!" set oldestVersion[%%b]=!version!
   )
)
rem Second pass: move all versions of each DocNumber, except the oldest one
for %%a in (*.pdf) do (
   for /F "tokens=1-4 delims=_" %%b in ("%%~Na") do (
      set version=%%e
      if not defined version set version=%%d
      if "!version!" neq "!oldestVersion[%%b]!" ECHO move "%%a" "C:\dest\dir"
   )
)

ディスク上のファイル:

00000056_NEWER WIDGET_Gray_W2.pdf
BI0000018307_MW531-ABZ2-Bond-Resc_xls_D2.pdf
BI0000018307_MW531-Triton-Bond-Res_xls_B9.pdf
BI0000018307_MW531-Triton-Bond-Res_xls_C5.pdf
D00003456_BTW-FW001_OPTB_A12.pdf
D00003456_BTW-FW001_OPTB_B9.pdf
D00003456_BTW-FW001_OPTB_C6.pdf
D00003456_BTW-FW001_OPTB_D2.pdf
DPP-456_BTW-FW001_OPTB_A1.pdf
DPP-456_BTW-FW001_OPTB_C45.pdf
DPP-456_NEW WIDGET_F6.pdf
DPP-456_NEWER WIDGET_Blue_W2.pdf
SD0001_ClassyWidget_C45.pdf
SD0001_I001_A1.pdf
SD0034_WIDGET_F6.pdf

プログラムの結果:

move "BI0000018307_MW531-Triton-Bond-Res_xls_B9.pdf" "C:\dest\dir"
move "BI0000018307_MW531-Triton-Bond-Res_xls_C5.pdf" "C:\dest\dir"
move "D00003456_BTW-FW001_OPTB_A12.pdf" "C:\dest\dir"
move "D00003456_BTW-FW001_OPTB_B9.pdf" "C:\dest\dir"
move "D00003456_BTW-FW001_OPTB_C6.pdf" "C:\dest\dir"
move "DPP-456_BTW-FW001_OPTB_A1.pdf" "C:\dest\dir"
move "DPP-456_BTW-FW001_OPTB_C45.pdf" "C:\dest\dir"
move "DPP-456_NEW WIDGET_F6.pdf" "C:\dest\dir"
move "SD0001_I001_A1.pdf" "C:\dest\dir"

編集同じ問題の3番目の解決策...

@echo off
setlocal EnableDelayedExpansion

rem Filename syntax: DocumentNumber_DocumentName_Version.pdf
rem May be spaces and underscores in DocumentName
rem Goal: Find last Version of same DocumentNumber and keep it (DocumentName don't cares)
rem       Move the rest to other folder

rem First pass: Create *ordered* FILE array with this format: FILE[docNumber,Version.pdf]=docName
for %%a in (*.pdf) do (
   set "fileName=%%a"
   rem Change spaces by slashes in DocumentName
   set fileName=!fileName: =/!
   rem DocumentNumber=first token, Version=last token; separated by underscores
   set docNumber=
   for %%b in (!fileName:_^= !) do (
      if not defined docNumber (
         set docNumber=%%b
      ) else (
         set Version=%%b
      )
   )   
   rem Eliminate DocumentNumber and Version from filename (get DocumentName)
   set fileName=!fileName:*_=!
   for %%v in (!Version!) do set docName=!filename:_%%v=!
   rem Create the array element, restoring spaces in DocumentName
   set FILE[!docNumber!,!Version!]=!docName:/= !
)

rem Delete REM part in two next commands if you want to review the created FILE array
REM SET FILE[
REM ECHO/

rem Second pass: Move all array elements of same DocumentNumber, except the last one
set docNumber=/
for /F "tokens=2-4 delims=[,]=" %%a in ('set FILE[') do (
   rem %%a=docNumber, %%b=Version.pdf, %%c=docName
   if "!docNumber!" equ "%%a" (
      ECHO move "!docNumber!_!docName!_!Version!" "C:\dest\dir"
   )
   set docNumber=%%a
   set docName=%%c
   set Version=%%b
)
于 2012-11-07T01:09:00.520 に答える