【问题标题】:Windows batch file: set string+number variables to contents of cmd-line parameters?Windows批处理文件:将字符串+数字变量设置为命令行参数的内容?
【发布时间】:2014-04-04 11:55:33
【问题描述】:

我正在尝试编写一个批处理文件,它将名为 VPARM1、VPARM2 等的变量设置为命令行变量 %1、%2 等的内容。这有一个转折点:如果%1、%2 等是现有文件的名称,我想将其解析为路径和文件名并清除原始变量。

在另一个线程中,Matt Williamson 向我展示了如何将现有文件的名称解析为其部分,如下所示(他的代码):

@echo off 
setlocal EnableDelayedExpansion

FOR %%a IN (%*) DO (
if exist %%a set VDOSPATH="%%~dpa"
if exist %%a set VDOSFILE="%%~nxa"
echo(!VDOSPATH! !VDOSFILE!
) 

我现在要做的是:如果 %1、%2 等不是现有文件名,我想将变量 VPARM# 设置为 %# 的内容,这样如果 %3 是“你好" 我想以 VPARM3="hello" 结尾,但如果 %2 是现有文件的名称,我不希望 VPARM2 存在。

我尝试了多种 FOR /L 和引号来处理 %1、%2 等,但根本没有任何效果。对于这方面的任何帮助,我将不胜感激。同样,答案对专家来说可能是显而易见的,但对我来说却不是。

附:我需要设置 VPARM 变量的原因是我的批处理文件打开了一个可以从环境中读取这些变量的程序。但另一个程序本身不接受参数,也不知道如何处理批处理文件中设置的 %1、%2 等。 (我希望这很清楚。)

编辑:感谢 Magoo 在下面的回答,我能够编写这个批处理文件(1)如果参数作为文件存在并且(2)将命令行参数解析为路径和文件名(VDOSPATH 和 VDOSFILE) ) 将其他命令行参数设置为新的命名参数(VPARM1、VPARM2 等):

setlocal EnableDelayedExpansion
set /a fcount=0
FOR %%a IN (%*) DO (
set /a fcount+=1
if exist %%a (
set VDOSPATH="%%~dpa"
set VDOSFILE="%%~nxa"
) else (
set VPARM!fcount!=%%a
)
)

再次感谢您!

【问题讨论】:

    标签: windows batch-file for-loop cmd


    【解决方案1】:
    @echo off 
    setlocal EnableDelayedExpansion
    
    :: remove variables starting fexists
    FOR  /F "delims==" %%a In ('set fexists 2^>Nul') DO SET "%%a="
    
    SET /a fcount=0
    
    FOR %%a IN (%*) DO (
     SET /a fcount+=1
     if exist %%a (
      SET "fexists!fcount!=%%a"
      set VDOSPATH="%%~dpa"
      set VDOSFILE="%%~nxa"
      echo(!VDOSPATH! !VDOSFILE!
     )
    )
    
    SET fexists
    
    GOTO :EOF
    

    如果您希望数字是连续的而不是位置的,请将 set /a fcount+=1 移动到 if exist 块中(即向下 1 行)


    添加,给定响应:

    @echo off 
    setlocal EnableDelayedExpansion
    
    :: remove variables starting fexists, notfexists
    For %%b IN (fexists notfexists) DO FOR  /F "delims==" %%a In ('set %%b 2^>Nul') DO SET "%%a="
    
    SET /a fcount=0
    SET "flist="
    SET "notflist="
    
    FOR %%a IN (%*) DO (
     SET /a fcount+=1
     if exist %%a (
      SET "flist=!flist! %%a"
      SET "fexists!fcount!=%%a"
      set VDOSPATH="%%~dpa"
      set VDOSFILE="%%~nxa"
      echo(!VDOSPATH! !VDOSFILE!
     ) ELSE (
      SET "notflist=!notflist! %%a"
      SET "notfexists!fcount!=%%a"
     )
    )
    
    SET fexists
    SET notfexists
    SET flist
    SET notflist
    
    GOTO :EOF
    

    在我的系统上,q22682214.bat 是批处理文件的名称,当前目录是 c:\106x,正在执行

    q22862214c xwsl.bat notme hello4 xx.csv what "\program files (x86)\desktop.ini" \pagefile.sys
    

    产量

    "c:\106x\" "xwsl.bat"
    "c:\106x\" "xx.csv"
    "c:\Program Files (x86)\" "desktop.ini"
    "c:\" "pagefile.sys"
    
    fexists1=xwsl.bat
    fexists4=xx.csv
    fexists6="\program files (x86)\desktop.ini"
    fexists7=\pagefile.sys
    
    notfexists2=notme
    notfexists3=hello4
    notfexists5=what
    
    flist= xwsl.bat xx.csv "\program files (x86)\desktop.ini" \pagefile.sys
    
    notflist= notme hello4 what
    

    (虽然我手动添加了一些空格以便于查看)

    for..%%b...for...%%a... 只是删除以fexistsnotfexists 开头的任何现有变量名,以便如果它们存在,它们将被删除。

    然后初始化 fcount 以计算已处理的参数并将列表字符串清空。

    对于每个参数,计算fcount 中的参数并测试它是否是现有文件名。

    如果是,将其累积到flist,将变量fexists# 设置为参数字符串并显示完整文件名的两部分 - 驱动器/路径和名称/扩展名。

    如果它不是现有文件名,则只需将其累积到notflist

    然后显示结果...

    恕我直言,提出此类问题的最佳方式是举例说明所需的输入条件和输出数据。

    【讨论】:

    • 感谢您的支持 - 但很抱歉,我对此知之甚少,无法确切了解效果。我看到如果我的命令行参数是 oneparam twoparm c:\filename,我以 fexists3=c:\filename 结尾。但是我没有看到如果 %3 包含存在的文件名,我如何清除 %3 。可能我以错误的方式问了这个问题,或者我根本不明白答案。很抱歉以这种方式回来寻求更多帮助。再次感谢!
    • 这正是我一直在寻找的:一千个感谢,并为没有明确说明我首先要寻找的内容而道歉。我会在未来解决这个问题。同时,这个论坛是一个了不起的资源——在我用前额敲打桌子解决了两个问题几个小时之后,答案几乎立即就到了。再次感谢您。
    • @emendelosn 只是一个提示 - 查看游览并注意绿色勾号。 stackoverflow.com/tour
    • 知道了!我没有意识到它就像点击绿色标记那么简单......我还添加了答案让我编写的批处理文件,这正是我所希望的。
    猜你喜欢
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    • 2012-11-29
    • 2011-09-10
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多