在批处理文件中执行子字符串的最佳方法是啥?
Posted
技术标签:
【中文标题】在批处理文件中执行子字符串的最佳方法是啥?【英文标题】:What is the best way to do a substring in a batch file?在批处理文件中执行子字符串的最佳方法是什么? 【发布时间】:2010-10-12 18:59:11 【问题描述】:我想获取当前运行的批处理文件的名称没有文件扩展名。
感谢this link,我有了带有扩展名的文件名...但是在批处理文件中创建子字符串的最佳方法是什么?
或者有没有其他方法可以获取不带扩展名的文件名?
在这种情况下假设 3 个字母扩展是安全的。
【问题讨论】:
【参考方案1】:好吧,要获取批处理的文件名,最简单的方法就是使用%~n0
。
@echo %~n0
将输出当前运行的批处理文件的名称(不带扩展名)(除非在call
调用的子例程中执行)。在帮助的最后,可以使用help for
找到此类“特殊”路径名替换的完整列表:
另外,替换 FOR 变量引用已得到增强。 您现在可以使用以下可选 语法:
%~I - expands %I removing any surrounding quotes (") %~fI - expands %I to a fully qualified path name %~dI - expands %I to a drive letter only %~pI - expands %I to a path only %~nI - expands %I to a file name only %~xI - expands %I to a file extension only %~sI - expanded path contains short names only %~aI - expands %I to file attributes of file %~tI - expands %I to date/time of file %~zI - expands %I to size of file %~$PATH:I - searches the directories listed in the PATH environment variable and expands %I to the fully qualified name of the first one found. If the environment variable name is not defined or the file is not found by the search, then this modifier expands to the empty string
修饰符可以组合得到 复合结果:
%~dpI - expands %I to a drive letter and path only %~nxI - expands %I to a file name and extension only %~fsI - expands %I to a full path name with short names only
但是,为了准确回答您的问题:子字符串使用 :~start,length
表示法完成:
%var:~10,5%
将从环境变量%var%
中的位置10提取5个字符。
注意:字符串的索引是从零开始的,所以第一个字符在位置 0,第二个在 1,依此类推。
要获取%0
、%1
等参数变量的子字符串,您必须首先使用set
将它们分配给普通环境变量:
:: Does not work:
@echo %1:~10,5
:: Assign argument to local variable first:
set var=%1
@echo %var:~10,5%
语法更加强大:
%var:~-7%
提取 %var%
的最后 7 个字符
%var:~0,-4%
将提取除最后四个字符之外的所有字符,这也会使您摆脱文件扩展名(假设句点 [.
] 后有三个字符)。
有关该语法的详细信息,请参阅help set
。
【讨论】:
子字符串提取也不适用于 FOR 循环变量,因此您必须执行以下操作(代码中的 \r\n 表示换行,因为 SO 似乎不允许在 cmets 中换行):setlocal ENABLEDELAYEDEXPANSION \r\n for /f %%s in ('set') do ( \r\n set tmp=%%s \r\n echo !tmp:~-3! \r\n )
@Fr0sT 为什么要为FOR
循环执行此操作?
@Adrian 为什么不呢? FOR
是批处理文件中的基石结构,可执行大量各种任务。顺便说一句,还有另一种方法可以通过使用子程序来处理任务,即for /f %%s in ('set') do call :DoSmth "%%s" \r\n ... \r\n :DoSmth \r\n set var=%1 \r\n echo %var:~1,3%
@Phate01,不要使用%date%
来构造特定格式的日期。格式特定于用户的文化,可能会发生变化。改用 WMI 以不依赖于用户设置的有用格式获取日期和时间。另外我不确定这条评论在这里做什么,因为这个问题与日期或时间无关。
其实你是对的,我想我想评论一个不同的问题:)【参考方案2】:
上面解释得很好!
对于所有可能像我一样在本地化的 Windows 中工作的人(我的是斯洛伐克的 XP),您可以尝试将 %
替换为 !
所以:
SET TEXT=Hello World
SET SUBSTRING=!TEXT:~3,5!
ECHO !SUBSTRING!
【讨论】:
请注意,这仅在setlocal ENABLEDELAYEDEXPANSION
命令后有效
试试SET TEXT="<Hello World>"
、SET SUBSTRING=!TEXT:~1,-1!
或SET SUBSTRING=%TEXT:~1,-1%
、ECHO !SUBSTRING!
或ECHO %SUBSTRING%
如何使用~othervar
代替~3
?它对我不起作用。【参考方案3】:
作为乔伊回答的附加信息,set /?
和 for /?
的帮助中没有描述。
%~0
扩展为自己的批次名称,与输入的完全相同。
所以如果你开始你的批处理,它将被扩展为
%~0 - mYbAtCh
%~n0 - mybatch
%~nx0 - mybatch.bat
但有一个例外,在子程序中展开可能会失败
echo main- %~0
call :myFunction
exit /b
:myFunction
echo func - %~0
echo func - %~n0
exit /b
结果
main - myBatch
Func - :myFunction
func - mybatch
在函数中,%~0
总是扩展为函数的名称,而不是批处理文件的名称。
但如果你至少使用一个修饰符,它会再次显示文件名!
【讨论】:
以上是关于在批处理文件中执行子字符串的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章