【问题标题】:Batch file to make folders and move files according to filenames批处理文件以根据文件名创建文件夹和移动文件
【发布时间】:2019-11-01 18:03:12
【问题描述】:

我是批处理脚本的新手,所以我很感激任何帮助。我在这里看到过类似的问题,但无法让我的移动功能正常工作。

我有以下格式的文件:

19013_01-PG-18-1000_NC_IL2RG_Ex2_F_D01.ab1
19013_01-PG-18-1000_NC_IL2RG_Ex2_R_H01.ab1

我想制作以下格式的文件夹:

01-PG-18-1000_NC_IL2RG_Ex2

然后将所有具有*01-PG-18-1000_NC* 的文件移动到该文件夹​​名称中。

这是我目前所拥有的。它以我想要的方式制作文件夹,但我根本无法移动文件。尝试了move 函数的多次迭代,但我并不完全理解令牌以及它与移动文件的关系。

@ECHO OFF
SETLOCAL
SET "sourcedir="whatever my directory name is"
PUSHD %sourcedir%
FOR /f "tokens=1,2,3,4,5 delims=_" %%a IN (
    'dir /b /a-d "*_*-*-*-*_*_*_*.*"'
) DO (  
    MD %%b_%%c_%%d_%%e 2>nul
    MOVE "%%b_%%c_%%d_%%e" "%%b_%%c_%%d_%%e"
)
POPD
GOTO :EOF

【问题讨论】:

  • 要格式化为代码,选择并按下编辑窗口上方的{}。请重新编辑您所做的任何重大更改。

标签: windows batch-file


【解决方案1】:

真正的快速 - 未经测试

@ECHO OFF
SETLOCAL
SET "sourcedir="whatever my directory name is"
PUSHD %sourcedir%
FOR /f "tokens=1,2,3,4,5,* delims=_" %%a IN (
    'dir /b /a-d "*_*-*-*-*_*_*_*.*"'
) DO (  
 echo ++%%a++%%b++%%c++%%d++%%e++%%f++
    MD %%b_%%c_%%d_%%e 2>nul
    MOVE "%%a_%%b_%%c_%%d_%%e_%%f" "%%b_%%c_%%d_%%e"
)
POPD
GOTO :EOF

您非常接近 - echo 行应该显示文件名如何解析为 %%a..%%f。由++分隔的部分,只是一个非常明显的分隔符,显示任何元素中是否有空格。

* 添加到令牌列表意味着“在提到的最高令牌号之后的所有内容”。然后从部分重构文件名 - 从%%a 开始串在一起,重新插入所有下划线。

这也应该有效:

@ECHO OFF
SETLOCAL
SET "sourcedir="whatever my directory name is"
PUSHD %sourcedir%
FOR /f %%q IN (
    'dir /b /a-d "*_*-*-*-*_*_*_*.*"'
) do (
 FOR /f "tokens=1,2,3,4,5,* delims=_" %%a IN ("%%q") do
    echo ++%%a++%%b++%%c++%%d++%%e++%%f++FROM++%%q++
    MD %%b_%%c_%%d_%%e 2>nul
    MOVE "%%q" "%%b_%%c_%%d_%%e"
 )
)
POPD
GOTO :EOF

在这个版本中,%%q 依次获取每个文件名,然后"%%q" 可以被for /f 解析,原始文件名在%%q 中保持不变,可以在move 语句中使用。

[实际上,很小的]修订:

REM <!-- language: lang-dos -->
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
PUSHD "%sourcedir%"
FOR /f "tokens=1,2,3,4,5,* delims=_" %%a IN (
    'dir /b /a-d "*_*-*-*-*_*_*_*.*"'
) DO IF EXIST "%%a_%%b_%%c_%%d_%%e_%%f" (  
    MD %%b_%%c_%%d_%%e 2>nul
    MOVE "*%%b_%%c*" "%%b_%%c_%%d_%%e"
)
POPD

SET "sourcedir=U:\sourcedir\t h r e e"
PUSHD "%sourcedir%"
FOR /f %%q IN (
    'dir /b /a-d "*_*-*-*-*_*_*_*.*"'
) do IF EXIST "%%q" (
 FOR /f "tokens=1,2,3,4,5 delims=_" %%a IN ("%%q") DO (
    MD %%b_%%c_%%d_%%e 2>nul
    MOVE "*%%b_%%c*" "%%b_%%c_%%d_%%e"
 )
)
POPD

GOTO :EOF

是的 - 误读了您想要移动所有包含的文件 - 整晚都在玩游戏...

上述批次分为两部分,第一部分使用%%a..%%f,第二部分包含%%q

面临的困难是move *[pattern]* 将根据需要移动所有文件,但for /f...'dir... 会构建一个列表,其中包含最初在目录中的所有匹配文件。

处理完第一个文件名后,那些包含 01-PG-18-1000_NC 的其他文件将被移动,因此列表中的下一个 01-PG-18-1000_NC 文件将出现“未找到文件”错误 for 有建成。

当然,可以组合一些机制来确保模式01-PG-18-1000_NC 只被处理一次,但是一个简单的if exists 用于for...%%a... 返回的完整文件名并重建可用于控制@987654346 @ 命令,因为在处理下一个 01-PG-18-1000_NC 时文件将不再存在(因为它已经被移动了)。不过使用%%q 方法要容易得多。

当然,您也可以简单地处理错误消息而不是安装门 - 但这可能被认为是粗鲁的。

如果您的文件名中有像 Space 之类的分隔符,那么 aschipfl 将 delims= 添加到 for...%%q... 的建议也是非常有效的(无论如何都不花钱)

哦 - 我在最初的回复中错过了 do 部分中的 ( - 当你没有实际测试代码时总是会发生这种情况,尤其是当你累了的时候。

【讨论】:

  • 感谢格式化和所有帮助,我非常感谢 Magoo。不幸的是,这两个选项仍然不起作用。它正在按照我想要的方式制作文件夹 %%b_%%c_%%d_%%e 01-PG-18-1300_NC_IL2RG_Ex2 但是移动“%%a_%%b_%%c_%%d_%%e_%%f”是它试图将只有 19013_01-PG-18-1300_NC_IL2RG_Ex2_F 的文件移动到文件夹“01-PG-18-1300_NC_IL2RG_Ex2”?虽然它也没有这样做。我应该同时使用“_”和“-”作为分隔符吗?任何更多的帮助将不胜感激!
  • @Moxy,你使用的是什么tokens 字符串? %%f 预计类似于 F_D01.ab1 (指您问题中的第一个示例文件)...
  • @Magoo,对于第二种方法,外部for /F 循环应该有delims= 选项,只是为了考虑潜在的空间......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多