使用regex基于文件名移动文件,并在文件名的子字符串中删除编号较小的文件

时间:2015-02-19 11:33:37

标签: regex windows powershell batch-file

我的文件使用以下语法:

LWD_???_??????_???_??_??_LP?_??_?_*.PDF

示例:

LWD_ARC_G10000_102_UE_XX_LP5_08_E_Uebersicht_Bodenplatten

我想从文件名中提取子字符串,并将文件放入一个文件夹,其中包含基于该文件名的路径,如下所示:

C:\Lp5\ARC\G10\

第一个文件夹是文件名的第7个部分,第2个部分是第二个文件夹,第3个部分的前3个字符是最后一个文件夹。

然后除了我需要额外删除:当文件被复制到特定文件夹时,文件名中有一个连续编号的部分。我需要删除“较旧”的文件,以便只有“最后”文件在此文件夹中。数字/索引始终是第30个和第31个字符。

LWD_FEU_L20000_005_IZ_00_LP8_XX_F.pdf      Index 00
LWD_FEU_L20000_005_IZ_00_LP8_01_F.pdf      Index 01 

现在我只有一个包含静态文件夹的批次:

FOR /R "E:\Downloads" %%i in (LWD_ELT_A10?00_???_??_??_LP5*) do move "%%i" "C:\Lp5\ELT\A10"
FOR /R "E:\Downloads" %%i in (LWD_???_A10000_???_??_??_LP5*) do del "%%i"
...

有没有人知道如何在没有VBS或某事的情况下做到这一点。那样 - 只有Windows Batch或PowerShell?

1 个答案:

答案 0 :(得分:0)

我的批量策略如下:

1)使用DIR / B获取PDF文件列表

2)将每个文件名解析为由(管道分隔)

组成的字符串
  • 与名称匹配的文件掩码,位置为30,31
  • ??通配符
  • 目标路径
  • 完整档案名称

3)对字符串进行降序排序,从而在每个文件名分组的顶部生成最新版本。

4)使用FOR / F处理输出,解析出文件掩码,目标路径和全名

5)对于每次迭代,创建目标文件夹(如果该文件夹尚不存在),然后在文件尚不存在与文件掩码匹配的情况下有条件地将文件复制到目标文件夹。

上述策略是非破坏性的,因为原始文件都保留在原位。您可以将步骤5修改为具有破坏性 - 移动最新文件而不是复制,然后删除其余文件。

您可以使用纯批次轻松实施上述策略。但我会使用我的REPL.BAT utility - 一个混合的JScript /批处理脚本,可以有效地执行复杂的正则表达式替换。 JREPL.BAT是纯脚本,可​​以在任何Windows机器上从XP开始本地运行。

以下是未经测试的

非破坏性版本

@echo off
for /f "tokens=1,2,3 delims=|" %%A in (
  'dir /b /a-d LWD_*.PDF ^| jrepl "^(LWD_(...)_(...)..._..._.._.._(LP.)_)..(_._.*\.PDF)$" "$1??$5|c:\$4\$2\$3|$&" /i /a ^| sort /r'
) do (
  md "%%B" >nul 2>nul
  if not exist "%%B\%%A" copy "%%C" "%%B" >nul
)

破坏性版本

@echo off
for /f "tokens=1,2,3 delims=|" %%A in (
  'dir /b /a-d LWD_*.PDF ^| jrepl "^(LWD_(...)_(...)..._..._.._.._(LP.)_)..(_._.*\.PDF)$" "$1??$5|c:\$4\$2\$3|$&" /i /a ^| sort /r'
) do (
  md "%%B" >nul 2>nul
  if not exist "%%B\%%A" (move "%%C" "%%B" >nul) else del "%%C"
)