我有一个使用变量的Windows cmd批处理文件,但在设置它之后使用该变量的任何地方都失败了。
这是我的批处理脚本:
@echo off
if exist Transactions.csv (
set datestr=%date:~10,4%%date:~7,2%%date:~4,2%%time:~0,2%%time:~3,2%%time:~6,2%
rename Transactions.csv Transactions-%datestr%.csv
curl -s -o curl.log --form upload=@Transactions-%datestr%.csv http://192.168.5.217/test_upload.php
set datestr=
)
文件被重命名为“Transactions-.csv”,curl命令工作正常,因为它按原样发送文件,但我希望它能正确地重命名文件。
如果我注释掉回线,我就会回来:
if exist Transactions.csv (
set datestr=20112206112720
rename Transactions.csv Transactions-.csv
curl -s -o curl.log --form upload=@Transactions-.csv http://192.168.5.217/test_upload.php
set datestr=
)
请注意缺少%datestr%的区域。
为什么没有正确解析这些变量的任何想法?
答案 0 :(得分:3)
当括号中包含一个命令块时,将在执行第一个命令之前解析整个块。这意味着,该块中的所有%var%
表达式都会被其当时的值替换。这就是为什么当您运行带有%datestr%
注释掉的脚本时,您无法取代@echo off
。
所以你决定将IF语句的正文移到括号之外是正确的。
另一个解决方案是使用延迟扩展:
@echo off
setlocal EnableDelayedExpansion
if exist Transactions.csv (
set datestr=!date:~10,4!!date:~7,2!!date:~4,2!!time:~0,2!!time:~3,2!time:~6,2!
rename Transactions.csv Transactions-!datestr!.csv
curl -s -o curl.log --form upload=@Transactions-!datestr!.csv http://192.168.5.217/test_upload.php
set datestr=
)
如您所见,使用setlocal EnableDelayedExpansion
命令引入了延迟扩展模式。另请注意语法的更改:!
而不是%
表示相应变量/表达式的延迟扩展。启用延迟展开后,您仍可以在适当的时候使用%
进行即时展开。
答案 1 :(得分:2)
请注意,这种解析日期的方式在很大程度上取决于所使用的语言环境。
%DATE%
使用完全(无限)可自定义的短日期格式返回当前日期。一个用户可以将其系统配置为返回Fri040811,另一个用户可以选择08/04/2011 ......对于BAT程序员来说,这是一个完整的噩梦。
这个问题有两个解决方案。
解决方案1,暂时更改区域设置。
reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f >nul
reg add "HKCU\Control Panel\International" /v sShortDate /d "yyyy-MM-dd" /f >nul
reg add "HKCU\Control Panel\International" /v sTimeFormat /d "HH:mm:ss" /f >nul
执行%DATE%逻辑,例如
set datestr=%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%
ren test.txt test-%datestr%.txt
然后恢复语言环境
reg copy "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f >nul
解决方案2.使用WMIC。
WMIC Path Win32_LocalTime Get Day,Hour,Minute,Month,Second,Year /Format:table
以方便的方式返回日期,以便用FOR。
直接解析它答案 2 :(得分:1)
如果我创建一个包含以下内容的批处理文件:
@echo off
set datestr=%date:~10,4%%date:~7,2%%date:~4,2%%time:~0,2%%time:~3,2%%time:~6,2%
echo Transactions.csv Transactions-%datestr%.csv
set datestr=
它显示:
C:\Temp>test
Transactions.csv Transactions-012/133612.csv
这告诉我实际导致失败的是您选择的datestr
格式 - 日期值包含正斜杠,在文件名中无效,这导致{{1 }} 失败。 (它必须是你在解析日期输出时使用的值;你有一个一个一个错误。)
您在硬编码测试中没有看到它,因为您已经对格式正确的日期进行了硬编码,而不是您在rename
中获得的日期。
答案 3 :(得分:1)
我将您的代码复制到.cmd脚本并运行它并成功重命名该文件。但是,我没有在括号中嵌套,而是使用了一个GoTo块引用,并在双引号内包含了datestr连接。这是我用过的代码......
@echo off
if exist test.txt (
goto RENFILE
) else (
goto NOTFOUND
)
:RENFILE
set datestr="%date:~10,4%%date:~7,2%%date:~4,2%%time:~0,2%%time:~3,2%%time:~6,2%"
echo %datestr%
rename test.txt test-%datestr%.txt
goto END
:NOTFOUND
echo file not found!
goto END
:END
pause