首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于文件名而不带分隔符的批处理移动,仅为字符串

问基于文件名而不带分隔符的批处理移动,仅为字符串
EN

Stack Overflow用户
提问于 2016-10-07 18:52:22
回答 3查看 313关注 0票数 2

好的,这里有一个Windows批处理文件问题的Windows 7企业x64。我是一个基本用户,对批处理文件的创建知之甚少。我已经修改了我在网上找到的现有脚本以供我使用,仅此而已。

我有一个软件,可以将它的输出转储到一个文件夹中,文件名与项目标题、当前系统日期、当前系统时间和项目设置连接在一起。

每次保存项目时,它都会以这种格式导出两个文件:

代码语言:javascript
复制
PROJECTTITLE_2016_10_07__09_45_11__A_B_C.iges
PROJECTTITLE_2016_10_07__09_45_11__A_B_C.step

A、B和C表示特定于项目的软件中使用的开关。它们可能存在,也可能不存在,因为文件名可以是_R_F或_R_F_Z等。"PROJECTTITLE“实际上可以是任何东西。这就是我使用分隔符产生问题的地方。您可能有类似于以下所有文件名(使用来自用户的实际示例):

代码语言:javascript
复制
11475shacklebody_2016_10_07__09_45_11__R_F.iges
11475shacklebody_2016_10_07__09_45_11__R_F.step
test_EFMflow_2016_10_07__09_45_11__R_Z.iges
test_EFMflow_2016_10_07__09_45_11__R_Z.step
untitled16_2016_10_07__09_45_11__R.iges
untitled16_2016_10_07__09_45_11__R.step
#14drop_wire-edm_2016_10_07__09_45_11__R_F_Z.iges
#14drop_wire-edm_2016_10_07__09_45_11__R_F_Z.step
prooftestwithoutupperlandsimproved-4_2016_10_07__09_45_11.iges
prooftestwithoutupperlandsimproved-4_2016_10_07__09_45_11.step

我想要做的是将IGES和STEP文件从C驱动器上的输出文件夹移到基于"PROJECTTITLE“的网络驱动器上的一个新文件夹中,如果需要的话创建该文件夹。我已经安排了一个基于-delim的批处理每晚运行的任务,但是发现分隔符不足以让我使用。

虽然这似乎是一项简单的工作,与分隔符,寻找第一个下划线,我有项目的下划线在他们的名字,混乱的文件夹命名。由于分隔符只适用于单个字符,而不是字符串,所以我一直在寻找批处理文件的示例--我可以适应我的使用,但没有找到任何类似于我想要做的事情--不使用分隔符。

搜索文件名中的字符串"_2016“似乎很简单,并在"_2016”之前接受所有字符,并创建一个新目录,将包含这些字符的文件放置在该文件夹中。但是,我不知道如何不使用分隔符来完成这个任务。

到目前为止,我使用分隔符查找下划线,创建文件夹并移动到映射驱动器上的文件夹:

代码语言:javascript
复制
for /f "delims=_" %%V in ('dir /b /a-d C:\Output\*_*.iges') do (
 mkdir "I:\ENG\PARTS\%%V" 2>nul
 move "C:\Output\%%V_*.iges" "I:\ENG\PARTS\%%V" >NUL 2>nul
 move "C:\Output\%%V_*.step" "I:\ENG\PARTS\%%V" >NUL 2>nul
)

这是一个非常简单的批处理文件,它所做的,但下降在它的脸与标题包含下划线。

几件事:

搜索_2016将意味着批处理文件将需要每年维护。我们可以搜索系统%

编辑:虽然并不理想,因为开关是有用的,但我在软件中找到了一种方法,在文件名的末尾不导出特定于项目的开关。所以现在出口应该是:

代码语言:javascript
复制
PROJECTTITLE_2016_10_07__09_45_11.iges
PROJECTTITLE_2016_10_07__09_45_11.step

我知道我可以从右边修剪,什么,21个字符,用这个名字创建一个文件夹,并在目录中搜索所有包含经过修剪的字符串的文件。

知道如何搜索特定的字符串仍然很好,尽管开关是完好无损的。我愿意学习,所以把所有的解释你的代码,你可以对我。

双(迟)编辑:优先,谢谢大家的回答,我非常感谢您的帮助。

文件名中的双下划线非常罕见,但确实会出现,可能是由于键入。这将成为一个更大的问题,因为我计划用它来移动的文件数量。该软件运行在大约100台用户机器上,有20多个用户,每个用户每天可以保存多达1000个文件。当用户运行仿真时,该软件将以增量方式自动保存。我试图给他们一种方式,让他们在网络上协作和查看彼此的仿真结果(我们积极鼓励他们使用这种方法),它认为软件是硬编码的输出到C驱动器(正如供应商告诉我的那样,用于“性能”)。我正在考虑把文件安排在OU中的每台PC上每15分钟移动一次,而不是每晚对他们正在做的事情提供一个近乎实时的视图。

我探索过的另一个选项是象征性地将每台机器上的输出文件夹链接到软件的文件夹网络驱动器,但发现这并不能真正解决用户的“组织”问题,就像将项目运行在同一个文件夹中一样。这也存在一个问题,即不允许他们在没有VPN的情况下将项目保存出办公室,一些用户会这样做,然后当他们回到办公室时将他们的文件移到办公室。

谢谢你的帮助。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-07 21:47:11

下一个批处理脚本应该完成这项工作,即使文件名包含cmd、有毒字符(如空格或%百分比符号等)。

代码语言:javascript
复制
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion

set "_fouts=C:\Output"           your setting
set "_fouts=D:\test\39924063"    my setting 

for /F %%G in ('wmic OS get localdatetime ^|find "."') do set "_fyear=%%G"

pushd "%_fouts%"
  set "_fyear=%_fyear:~0,4%"
  call :doDir
  set /A _fyear -= 1
  call :doDir
popd

ENDLOCAL
goto :eof

:doDir
rem debugging output echo(%_fyear%
for /f "delims=" %%V in ('
  dir /b /a-d "*_%_fyear%_*.iges" "*_%_fyear%_*.step" 2^>NUL') do (
    set "_fname=%%~nV"           filename without extesion
    set "_fexte=%%~xV"           extesion only
    call :doAll
)
goto :eof

:doAll
    call set "_ftail=%%_fname:*_%_fyear%_=%%"
    call set "_fproj=%%_fname:_%_fyear%_%_ftail%=%%"
    rem debugging output echo("%_fproj%" "%_fname%" "%_fexte%"
    ECHO mkdir "I:\ENG\PARTS\%_fproj%" 2>nul
    ECHO move "%_fname%%_fexte%" "I:\ENG\PARTS\%_fproj%\"
goto :eof

Output (请注意,操作的mkdir和move命令仅用于使用ECHO mkdir和ECHO move进行调试):

代码语言:javascript
复制
==> dir /B /S "D:\test\39924063" /S
D:\test\39924063\#14drop_wire-edm_2016_10_07__09_45_11__R_F_Z.iges
D:\test\39924063\#14drop_wire-edm_2016_10_07__09_45_11__R_F_Z.step
D:\test\39924063\%PROJECT TITLE_2016_10_07__09_45_11__A_B_C.iges
D:\test\39924063\%PROJECT TITLE_2016_10_07__09_45_11__A_B_C.step

==> D:\bat\SO\39924063.bat
mkdir "I:\ENG\PARTS\#14drop_wire-edm"
move "#14drop_wire-edm_2016_10_07__09_45_11__R_F_Z.iges" "I:\ENG\PARTS\#14drop_wire-edm\"
mkdir "I:\ENG\PARTS\%PROJECT TITLE"
move "%PROJECT TITLE_2016_10_07__09_45_11__A_B_C.iges" "I:\ENG\PARTS\%PROJECT TITLE\"
mkdir "I:\ENG\PARTS\#14drop_wire-edm"
move "#14drop_wire-edm_2016_10_07__09_45_11__R_F_Z.step" "I:\ENG\PARTS\#14drop_wire-edm\"
mkdir "I:\ENG\PARTS\%PROJECT TITLE"
move "%PROJECT TITLE_2016_10_07__09_45_11__A_B_C.step" "I:\ENG\PARTS\%PROJECT TITLE\"

==>

Resources (必需阅读,不完整):

票数 1
EN

Stack Overflow用户

发布于 2016-10-08 12:13:54

如果文件名的PROJECTTITLE部分不包含两个连续下划线,则可以使用以下脚本,该脚本使用标准的__循环而不是for /F来拆分第一次出现的for和之后的一切(因此时间部分和可选开关被移除);然后使用子字符串展开将另外11个字符(因此是剩余的日期部分)拆分:

代码语言:javascript
复制
@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SOURCE=."
set "_TARGET=."

for /F delims^=^ eol^= %%F in ('
    pushd "%_SOURCE%" ^&^& ^(
    dir /B /A:-D ^
        "*_????_??_??__??_??_??*.iges" ^
        "*_????_??_??__??_??_??*.step" ^
    ^& popd^)
') do (
    call :PROCESS "%%F"
)

endlocal
exit /B


:PROCESS  val_file
setlocal DisableDelayedExpansion
set "FILE=%~1"
setlocal EnableDelayedExpansion
for %%I in ("!FILE:__=";"!") do (
    endlocal
    set "ITEM=%%~I"
    setlocal EnableDelayedExpansion
    goto :NEXT
)
:NEXT
if defined ITEM (
    set "ITEM=!ITEM:~,-11!"
    md "%_TARGET%\!ITEM!" 2> nul
    if not exist "%_TARGET%\!ITEM!\!FILE!" (
        move /Y "%_SOURCE%\!FILE!" "%_TARGET%\!ITEM!\" > nul
    )
)
endlocal
endlocal
exit /B

最后,我想出了一个脚本,它甚至能够处理那些PROJECTTITLE部分本身包含__的文件。它使用标准的__循环(而不是for /F)将最后出现的for和所有内容(因此可选的开关被移除,如果有的话,或者时间部分被移除);然后使用子字符串展开来拆分另外21个字符(因此是剩余的日期和时间部分),或者,如果没有可选的开关,则使用子字符串展开来拆分另外11个字符(因此是剩余的日期部分):

代码语言:javascript
复制
@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SOURCE=."
set "_TARGET=."

for /F delims^=^ eol^= %%F in ('
    pushd "%_SOURCE%" ^&^& ^(
    dir /B /A:-D ^
        "*_????_??_??__??_??_??*.iges" ^
        "*_????_??_??__??_??_??*.step" ^
    ^& popd^)
') do (
    call :PROCESS "%%F"
)

endlocal
exit /B


:PROCESS  val_file
setlocal DisableDelayedExpansion
set "FILE=%~1"
set "BASE=%~n1"
set "NAME=" & set "ITEM="
setlocal EnableDelayedExpansion
for %%I in ("!BASE:__=";"!") do (
    for /F "delims=" %%E in ("!NAME!!ITEM!__") do (
        endlocal
        set "NAME=%%E"
        set "ITEM=%%~I"
        setlocal EnableDelayedExpansion
    )
)
if defined NAME (
    set "NAME=!NAME:~2,-2!"
    echo("!ITEM!"| > nul findstr /R "^\"[0-9][0-9]_[0-9][0-9]_[0-9][0-9]\"$" || (
        if defined NAME set "NAME=!NAME:~,-10!"
    )
    if defined NAME set "NAME=!NAME:~,-11!"
    if defined NAME (
        md "%_TARGET%\!NAME!" 2> nul
        if not exist "%_TARGET%\!NAME!\!FILE!" (
            move /Y "%_SOURCE%\!FILE!" "%_TARGET%\!NAME!\" > nul
        )
    )
)
endlocal
endlocal
exit /B
票数 1
EN

Stack Overflow用户

发布于 2016-10-08 14:01:00

这个版本假设_YYYY_在PROJECTTITLE中不会有一个实例。

代码语言:javascript
复制
@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

(Set OutDir=I:\ENG\PARTS)
(Set SrcDir=C:\Output)

If Not Exist "%SrcDir%\" Exit/B 1
If Not Exist "%OutDir%\" Exit/B 1
For /F "EOL=Y" %%A In ('WMIC Path Win32_LocalTime Get Year') Do (
    For /F "Delims=" %%B In ("%%A") Do Set "ThisYr=%%B")
For /F "Delims=" %%A In ('Where "%SrcDir%:*_%ThisYr%_*.iges"') Do (
    If Exist "%%~dpnA.step" Call :Sub %%~nA)
Exit/B

:Sub
Set "BigTit=%~1"
For /F "Delims=" %%A In ('CMD /Q /C "Call Echo %%BigTit:_%ThisYr%_=&:%%"') Do (
    If Not Exist "%OutDir%\%%A\" MD "%OutDir%\%%A"
    Move "%SrcDir%\%~1*.*" "%OutDir%\%%A">Nul)

编辑__,如果没有使用上述代码的潜在有用的项目开关,就不需要导出。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39924063

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档