我有一个使用variables的Windows CMDbatch file,但无论设置它失败后使用该variables。
这是我的批处理脚本:
@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%应该在的缺失区域。
任何想法为什么这些variables没有正确parsing?
当括号中包含一个命令块时,整个块将在第一个命令执行之前被解析。 这意味着,该块内的所有%var%
表达式将被替换为当时的值。 这就是为什么当你使用@echo off
注释掉脚本的时候,你可能看不到%datestr%
。
所以你决定把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
命令引入的。 还要注意语法的变化: !
而不是%
表示相应变量/表达式的延迟扩展。 如果启用延迟扩展,则可以在适当的情况下使用%
进行立即扩展。
请注意,这种解析日期的方式在很大程度上取决于所使用的语言环境。 %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解析。
如果我使用以下内容创建批处理文件:
@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
格式 – 日期值包含一个正斜杠,这在文件名中是无效的,这导致rename
失败。 (这是你在解析日期输出时使用的值,你有一个错误的错误。)
您在硬编码测试中没有看到它,因为您已经对格式正确的日期进行了硬编码,而不是您在datestr
获得的datestr
。
我将你的代码复制到一个.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