我正在尝试编写一个批处理文件,将名为 VPARM1、VPARM2 等的变量设置为命令行变量 %1、%2 等的内容。这有一个转折点:如果%1, %2, etc 是现有文件的名称,我想将其解析为路径和文件名并清除原始变量。
在另一个线程中,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 是“hello "我想以 VPARM3="hello"结束,但如果 %2 是现有文件的名称,我不希望 VPARM2 存在。
我尝试了多种 FOR/L 和引号来处理 %1、%2 等,但根本不起作用。对于这方面的任何帮助,我将不胜感激。同样,答案对专家来说可能是显而易见的,但对我来说却不是。
附言我需要设置 VPARM 变量的原因是我的批处理文件打开了一个可以从环境中读取这些变量的程序。但是另一个程序本身不接受参数,并且不知道如何处理批处理文件中设置的 %1、%2 等。 (我希望这很清楚。)
编辑:感谢 Magoo 在下面的回答,我能够编写这个批处理文件,它 (1) 将命令行参数解析为路径和文件名(VDOSPATH 和 VDOSFILE),如果该参数作为文件存在,并且 (2 ) 将其他命令行参数设置为新的命名参数(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
)
)
再次感谢!
最佳答案
@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
block 中(即向下 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...
简单地删除任何以 fexists
或 notfexists< 开头的现有变量名
以便如果它们存在,它们将被删除。
然后初始化 fcount
以计算处理的参数和列表字符串为空。
对于每个参数,在fcount
中计数参数并测试它是否是现有文件名。
如果是,将其累积到 flist
中,将变量 fexists#
设置为参数字符串并显示完整文件名的两部分 - 驱动器/路径和名称/扩展名。
如果它不是一个存在的文件名,那么简单地将它累积到notflist
然后显示结果...
恕我直言,提出此类问题的最佳方式是举例说明所需的输入条件和输出数据。
关于Windows 批处理文件 : set string+number variables to contents of cmd-line parameters?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22862144/