【问题标题】:Batch file set to pick a random file from preset categories is not picking a random file (keeps picking the last file!)设置为从预设类别中选择随机文件的批处理文件未选择随机文件(继续选择最后一个文件!)
【发布时间】:2019-12-28 09:07:11
【问题描述】:

晚上好。我喜欢在空闲时间修改游戏,这是一种将单个模组打包到 zip 文件中并通过简单地将所述 zip 放入某个文件夹来加载的游戏。我有数百个这样的 zip 并且希望制作一个批次,每次我使用它时都会为我挑选一个随机的 mod,而不必自己挑选它们,同时将所有未使用的拉链放入我制作的禁用文件夹中将所有不被使用的东西都放在一个地方。每个模组都有一个名称前缀,表示它所属的类别,例如“weapon_shotgun_GiantAngryGun9000.zip”或“character_huck_Clown.zip”

这个批处理脚本的工作原理是首先它会获取当前在 mod 文件夹中具有指定前缀的每个文件,并将它们全部放入禁用的文件夹中。然后它会遍历禁用文件夹中具有所有指定前缀的每个文件,从每个类别中选择一个随机文件,并将它们移动到 mod 文件夹中。目前,我已经让我的批次完成所有解释,除了不是随机选择每个,而是从每个前缀列表中选择按字母顺序排列的最后一个。我相信这是因为用于指定 File 数组中条目索引的 Num var 没有被修改或读取,尽管我尽了最大努力,但我无法让它按我希望的方式工作。

感谢任何建议或解决方案,感谢您的阅读。

setlocal EnableDelayedExpansion

SET modFolder="C:\Game\Mods\"
SET disabledFolder="C:\Game\Mods\Disabled\"
SET itemListIndex=0

::Prefix names
SET Prefix1=Weapon_Shotgun_
set itemList[%itemListIndex%]=%Prefix1%
set /A itemListIndex+=1

SET Prefix2=Character_ThisPerson_
set itemList[%itemListIndex%]=%Prefix2%
set /A itemListIndex+=1

SET Prefix3=Weapon_Rifle_
set itemList[%itemListIndex%]=%Prefix3%
set /A itemListIndex+=1


for /l %%G in (0 1 %itemListIndex%) do (
    if not "!itemList[%%G]!" == "" (
        set num=0
        for %%f in (!itemList[%%G]!*.zip) do (
           set /A num+=1
           set file[%num%]=%%f
        )
        set /A pick = !random! * %num% / 32768 + 1
        echo Moving "!file[%pick%]!" to the mod folder
        move "%disabledFolder%!file[%pick%]!" %modFolder%
    )
)

set file[%num%]=%%f 回显为set file[]='[name of file]',而不是预期的set file['(index number)']='[name of file]'

书面回声说Moving !file[]! to the mod folder,而不是预期的Moving (name of file) to the mod folder

pick 变量回显为空白,表示 num 或 random 无效

【问题讨论】:

    标签: batch-file random


    【解决方案1】:
    @ECHO OFF
    setlocal EnableDelayedExpansion
    
    SET modFolder="C:\Game\Mods\"
    SET disabledFolder="C:\Game\Mods\Disabled\"
    SET itemListIndex=0
    
    ::Prefix names
    SET Prefix1=Weapon_Shotgun_
    set itemList[%itemListIndex%]=%Prefix1%
    set /A itemListIndex+=1
    
    SET Prefix2=Character_ThisPerson_
    set itemList[%itemListIndex%]=%Prefix2%
    set /A itemListIndex+=1
    
    SET Prefix3=Weapon_Rifle_
    set itemList[%itemListIndex%]=%Prefix3%
    set /A itemListIndex+=1
    
    for /l %%G in (0 1 %itemListIndex%) do (
        if not "!itemList[%%G]!" == "" (
            set num=0
            for %%f in (!itemList[%%G]!*.zip) do (
               set /A num+=1
               set file[!num!]=%%f
            )
            set /A pick = !random! * !num! / 32768 + 1
            CALL SET "PICKFILE=%%file[!pick!]%%"
            REM echo Moving "!file[%pick%]!" to the mod folder
            REM ECHO move "%disabledFolder%!file[%pick%]!" %modFolder%
            echo Moving "!pickfile!" to the mod folder
            ECHO move "%disabledFolder%!pickfile!" %modFolder%
        )
    )
    
    
    GOTO :EOF
    

    您的问题是 %num%%pick% 是解析外循环 (%%G) 时 num 和 ``pick` 的值,即 nothing

    经典的方法是使用!num! 作为运行时值,但您使用的是间接方式,因此您很想使用!file[!pick!]!,它是模棱两可的并解析为pickcall 使用子shell 来解决歧义。

    Move 命令被echoed 解除武装。

    【讨论】:

      【解决方案2】:

      尽管已经收到并接受了答案,但我还是决定发布此内容以向您展示我将如何做到这一点。

      @Echo Off
      SetLocal EnableDelayedExpansion
      
      Set "modFolder=C:\Game\Mods"
      Set "disabledFolder=C:\Game\Mods\Disabled"
      
      Rem Undefine existing variables
      For /F "Delims==" %%A In ('Set item 2^>NUL') Do Set "%%A="
      
      Rem Define filename prefixes
      Set "itemListIndex=0"
      For %%A In (
          Weapon_Shotgun
          Character_ThisPerson
          Weapon_Rifle
      ) Do (Set /A itemListIndex+=1
          Set "itemList[!itemListIndex!]=%%A_")
      
      Rem Randomize itemListIndex
      Set /A itemListIndex=(%RANDOM% %% itemListIndex)+1
      
      Rem Define files based upon itemList[%itemListIndex%] 
      Set "itemFileIndex=0"
      For %%A In ("!itemList[%itemListIndex%]!*.zip") Do (Set /A itemFileIndex+=1
          Set "itemFile[!itemFileIndex!]=%%A")
      
      Rem Randomize itemFileIndex
      Set /A itemFileIndex=(%RANDOM% %% itemFileIndex)+1
      
      Rem Move itemFile[%itemFileIndex%] to modFolder.
      Echo Moving "!itemFile[%itemFileIndex%]!" to the mod folder
      Move /Y "%disabledFolder%\!itemFile[%itemFileIndex%]!" "%modFolder%"
      Pause
      

      这样,您可以轻松地附加到带括号的前缀列表中(这既可以显着减少您的代码,也可以使其更易于维护)。首先随机化itemListIndex 也更有意义,以减少返回的用于选择/移动的.zip 文件的数量。

      【讨论】:

        猜你喜欢
        • 2017-01-25
        • 1970-01-01
        • 2014-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-03
        • 2017-03-10
        • 1970-01-01
        相关资源
        最近更新 更多