【问题标题】:Batch: Assigning variable name of file that is originally pointed as wildcard批处理:分配最初指向通配符的文件的变量名
【发布时间】:2017-05-31 05:12:37
【问题描述】:

我有一个编译源映射的脚本,但我能做到这一点的唯一方法是制作 map(.vmf) 文件的副本并将其命名为 mapCompiler_copy。我需要这样做,因为用于编译地图的程序在识别地图文件时必须具有特定的名称。

假设我在一个文件夹中只有一个 .vmf 文件,假设它是:

C:\CompilerScript\myMap.vmf

在不知道地图文件名称的情况下,如何使用批处理脚本将名称“myMap”分配给变量?(因为不同的人会有不同的地图名称)。

set mapfolder=%1
set mapname=mapCompiler_copy.vmf
set mapname_bsp=mapCompiler_copy
copy /B %1\*.vmf %1\%mapname%
set map="%mapfolder%\%mapname%"

这就是脚本现在的工作方式,在其中您将文件夹拖放到脚本上,脚本会复制地图文件并将其命名为 mapCompiler_copy.vmf,我稍后会在程序中使用它,例如:

call vbsp.exe -notjunc -leaktest -game "C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Source\cstrike" %map%

编辑:更具体地说,我将一个文件夹拖放到脚本中,这个文件夹的唯一内容是地图文件(.vmf)。我希望脚本能够存储地图的名称,唯一的信息是扩展名是 (.vmf),并且文件夹内只有一个地图文件。这是因为不同的人编译多张地图会有不同的地图文件名称

【问题讨论】:

    标签: batch-file cmd wildcard


    【解决方案1】:

    我会做以下事情:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem // Define constants here:
    set "_FEXT=.vmf"
    set "_NEXT=.bsp"
    
    rem // Check (path) argument whether it exists:
    if not exist "%~1" (>&2 echo ERROR: file not found!) & exit /B 1
    rem // Check for directory or for file type (extension):
    set "ATTR=%~a1"
    if "%ATTR:~,1%"=="d" (
        rem // Argument is a directory, so get first matching file:
        set "FILE=" & set "NAME="
        for %%F in ("%~1\*%_FEXT%") do if not defined FILE (
            set "FILE=%%~fF" & set "NAME=%%~nxF"
            set "FNEW=%%~dpnF%_NEXT%" & set "NNEW=%%~nF%_NEXT%"
        )
    ) else if /I "%~x1"=="%_FEXT%" (
        rem // Argument is a file, so check its type (extension):
        set "FILE=%~f1" & set "NAME=%~nx1"
        set "FNEW=%~dpn1%_NEXT%" & set "NNEW=%~n1%_NEXT%"
    )
    rem // Check if a matching file has been found:
    if not defined FILE (>&2 echo ERROR: file not found!) & exit /B 1
    
    rem // Return found file:
    echo or. path: "%FILE%"
    echo or. name: "%NAME%"
    echo new path: "%FNEW%"
    echo new name: "%NNEW%"
    
    endlocal
    exit /B
    

    因此,如果将文件拖放到批处理脚本上,则会根据.vmf 检查其扩展名(类型),如果匹配,则返回其路径和名称。 如果将目录拖放到批处理脚本上,则会检查其内容(直接子文件)并返回找到的第一个扩展名为 .vmf 的文件的路径和名称。

    【讨论】:

    • 这个解决方案效果很好,但是有什么方法可以让我也可以将相同的地图名称分配给最后带有 .bsp 的变量?这是为了在编译后,我需要将它复制到 cstrike maps 文件夹并使用该地图启动游戏,但只能使用 .bsp 文件而不是 .vmf 文件?
    • 虽然这确实有效,但每当我将 %FILE% 用于编译程序时,它都会指向其他内容。是不是需要把整个程序封装起来,把endlocal放在最后?
    • 还有一种方法可以对地图名称进行子串化以获取没有扩展名的名称。当向游戏控制台传递命令时,游戏知道它是一个 .bsp 并且它已经在相应的地图文件夹中,因此您只能传递不带“.bsp”和结尾的地图名称。
    • 变量在endlocal之后会丢失,所以要么在endlocal之前插入编译器程序调用,要么去掉初始的setlocalendlocal...
    • 只需将set "_NEXT=.bsp" 更改为set "_NEXT=",这样就不再附加.bsp 扩展...
    【解决方案2】:

    我认为以下内容可能会对您有所帮助。我的假设是文件扩展名的长度始终为 3(和一个句点)

    @echo off
    Set fullpath=C:\CompilerScript\myMap.vmf
    For %%A in ("%fullpath%") do (
        Set Name=%%~nxA
    )
    echo %Name:~0,-4%
    

    【讨论】:

    • Set "Name=%%~nA" 没有任何先决条件。
    • 如果我不知道文件名,但我知道扩展名,这是否可行。例如,如果 mapnane 是 rp_downtown_complex。 vmf,我需要指定吗?
    • 建议的答案应该提取任意长度的文件名,只要文件扩展名是 3 个字符长。您可以对此进行测试并自己确认。
    猜你喜欢
    • 2011-05-15
    • 2018-12-12
    • 2016-12-07
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    相关资源
    最近更新 更多