gpt4 book ai didi

batch-file - 具有常量的变量的批处理文件比较失败

转载 作者:行者123 更新时间:2023-12-01 04:34:01 25 4
gpt4 key购买 nike

我想编写一段简单的代码来获取一些格式良好的“时间戳”。
将时间花在我的两个变量StartEnd上工作正常。我也可以将其打印为0:0:0。我想要一个小于零的前导零,但是很显然我得到一个错误,说“未找到或错误键入参数10”。
我发现这似乎是要比较的变量,但未能解决。有任何想法吗?

@ECHO OFF
REM Time Calculation
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."') DO (
set Day=%%A
set Hour=%%B
set Minute=%%C
set Second=%%D
)
set /a Start=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100
@ECHO ON
ping 8.8.8.8 -n 11
@ECHO OFF
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."') DO (
set Day=%%A
set Hour=%%B
set Minute=%%C
set Second=%%D
)
set /a End=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100
set /a Diff=%End%-%Start%
set /a Diff=(%Diff%)/100
set /a DiffSec=%Diff%%%60
set /a Diff=(%Diff%-%Diff%%%60)/60
set /a DiffMin=%Diff%%%60
set /a Diff=(%Diff%-%Diff%%%60)/60
set /a DiffHrs=%Diff%

ECHO Laufzeit Auftraege loeschen: %DiffHrs%:%DiffMin%:%DiffSec%

:: format with leading zeroes
if %DiffSec% LSS 10 (ECHO "LESS 10")else %DiffSec% LSS 1 (ECHO "LESS 1")
::if %DiffSec% LSS 10 (set DiffSec=0%DiffSec%)else [%DiffSec%] LSS 1 (set DiffSec=00)
::if %DiffMin% LSS 10 (set DiffMin=0%DiffMin%)else [%DiffMin%] LSS 1 (set DiffMin=00)
::if %DiffHrs% LSS 10 (set DiffHrs=0%DiffHrs%)else [%DiffHrs%] LSS 1 (set DiffHrs=00)

ECHO Laufzeit Auftraege loeschen: %DiffHrs%:%DiffMin%:%DiffSec%

最佳答案

1.调试批处理文件

为了调试批处理文件以查找代码中的语法错误,建议在将每个echo off修改为echo ON或从批处理文件中删除或用命令REM注释掉后,从命令提示符窗口中运行该批处理文件。

默认情况下,Windows命令解释器在分析和预处理后输出每个命令行或整个命令块,这些命令块或整个命令块以(开头并以匹配的)结尾,在该字符串上,已经用%variable%引用的环境变量(立即扩展)替换了执行命令行/块之前的环境变量。

在批处理文件顶部使用@echo off时,此默认行为已关闭,从而在命令行开头的@也禁用了该第一个命令行的输出。当批处理文件的开发完成并且批处理文件运行正常时,当然欢迎您。但是,对于调试无法按预期方式运行的批处理文件,最好还要查看由命令解释器实际执行的命令行,以找出由于错误而意外退出了批处理文件的执行位置。

在命令提示符窗口中运行echo /?的帮助输出中,非常简短地说明了ECHO行为。

打开命令提示符窗口将导致使用选项cmd.exe隐式启动/K,以保持命令进程运行,并且在批处理文件或应用程序执行完成后,控制台窗口将打开。

批处理文件包含不带参数exit的命令/B时是一个例外,因为在这种情况下,当前命令进程始终独立于调用层次结构而退出。 exit /B等于goto :EOF,应该使用它而不是仅仅使用exit,除非确实有充分的理由只使用exitexit /Bgoto :EOF都需要Windows默认情况下启用的两个命令扩展名。

双击批处理文件会导致使用选项cmd.exe启动/C,从而在结束应用程序或批处理文件的执行时自动关闭命令进程及其控制台窗口,而与批处理文件的执行终止的原因无关。自动关闭控制台窗口的行为不适用于调试批处理文件,因为批处理文件执行由于语法错误而终止时,看不到错误消息。

有关在命令提示符窗口中运行的Windows命令解释器选项的更多详细信息,请执行以下命令:cmd /?

在运行这两个命令的帮助下,说明了如何使用goto :EOF(冒号在这里很重要,作为例外)或exit /B(只是goto :EOF的内部别名)有意退出批处理文件的执行。 cc>和goto /?在命令提示符窗口中。

对于调试较大的批处理文件,使用在批处理文件顶部临时添加的exit /?跳转到某个块,然后使用goto退出要调试的块后退出批处理可能会有所帮助。

顺便说一句:goto :EOF是无效的标签,通常用于批处理文件中的注释,因为在执行批处理文件时永远不会显示标签行。但是在FOR循环的命令块中不能使用标签,因为Windows命令解释器无法正确解释在命令块中带有标签的FOR循环。因此,最好使用命令REM(注释)进行注释,因为此命令是为批处理文件中的注释设计的,并且实际上可以在批处理文件中的任何位置使用。

2.批处理文件中的错误

在命令提示符窗口中运行有问题的发布的批处理文件时,都用::替换了注释中的两个@ECHO OFF(在文本编辑器中运行替换),可以很容易地看到错误发生在哪一行:

if %DiffSec% LSS 10 (ECHO "LESS 10")else %DiffSec% LSS 1 (ECHO "LESS 1")


如果环境变量 rem @echo off的当前值不小于 DiffSec,则ELSE分支由Windows命令解释器执行,该命令解释器以类似 10的数字开头。

Windows命令解释器无法在当前目录或环境变量 10的分号分隔目录列表中指定的任何目录中找到具有该名称的应用程序,该目录具有在环境变量 PATH的分号分隔文件扩展名列表中指定的文件扩展名。

此处的错误显然是缺少下一个比较的IF命令。所以正确的代码是

if %DiffSec% LSS 10 (ECHO "LESS 10") else if %DiffSec% LSS 1 ECHO "LESS 1"


在多行写入条件时,这将更容易阅读:

if %DiffSec% LSS 10 (
ECHO "LESS 10"
) else if %DiffSec% LSS 1 (
ECHO "LESS 1"
)


语法现在是正确的。

但是第二个条件没有意义,正如 JosefZ在他的评论中已经提到的那样。如果 PATHEXT的值为10或更大,导致在ELSE分支中执行IF命令,则此条件绝对也不会成立。因此更有意义:

if %DiffSec% LSS 1 (ECHO LESS 1) else if %DiffSec% LSS 10 ECHO LESS 10


或者

if %DiffSec% LSS 1 (
ECHO LESS 1
) else if %DiffSec% LSS 10 (
ECHO LESS 10
)


有关批处理文件中有效IF ELSE条件的更多信息,请参见例如


IF ELSE syntax error within batch file?
batch scripting - if exist ./sdcard/file.any using adb


3.为数字<10添加前导零

环境变量始终为字符串类型。对于算术表达式,如果可能的话,将环境变量的字符串值转换为有符号的32位整数,并且将算术表达式的结果从有符号的32位整数转换回字符串。

同样,IF条件(例如 DiffSec在执行之前被扩展为例如 if %DiffSec% LSS 10)也会导致将 if 5 LSS 10(0x35)从字符串转换为整数,并且将 5(0x31 0x30)也从字符串转换为整数,以便将两个数字进行比较整数。

因此,如果可能的话,避免这种数字比较会更快一些。

在不使用字符串替换真正测试值的情况下,将前导零添加到小于10的数字是很容易的。

首先,环境变量的当前值以一个(对于两位数的数字)或更大的 10(对于3、4甚至更大的数字)为前缀。

set "DiffSec=0%DiffSec%"


接下来,从环境变量的当前值到环境变量分配最后的X个字符(例如2代表两位数字)。

set "DiffSec=%DiffSec:~-2%"


通过在命令提示符窗口 0中运行,可在命令SET输出的帮助下解释字符串替换。

这两行的结果是,在这两行之后, set /?的值分别为 DiffSec0,其值始终是在 9900范围内的两位数字。

4.解析算术表达式

Windows命令解释器解释的算术表达式( 99之后的字符串)与其他字符串完全不同。

空格和制表符是单词分隔符,但没有其他特殊含义。因此,建议使用空格使算术表达式更易读。

然后,在命令提示符窗口 set /a中运行时显示的命令SET的帮助下列出了许多运算符。

另外的十进制,八进制和十六进制整数在算术表达式中解释为整数。

最后每隔一个字符串将被解释为环境变量的名称,该环境变量的当前值从字符串转换为整数。

因此,不建议在算术表达式中使用立即扩展或延迟扩展。

当在命令块中使用环境变量的当前值替换在执行第一个命令之前解析整个命令块时已经存在的变量引用的命令块中时,在算术表达式中用 set /?引用环境变量的值是不好的。

在算术表达式中用 %variable%引用环境变量的值也不是一件好事,因为它需要启用延迟扩展,这导致将字符串中的感叹号不再作为文字字符来处理。

因此,最好的办法是始终简单地在算术表达式中写变量名,如果可能,因为变量名不包含空格字符并且以Windows不能将其解释为整数字符的形式出现,则不要用百分号或感叹号引起来命令解释器。

另请参见 Why is no string output with 'echo %var%' after using 'set var = text' on command line?上的答案,以获取有关如何仅使用 !variable!set(提示)或 set /P(算术表达式)将值分配给环境变量的详细信息。

5.固定和优化的代码

有问题的代码可以固定为此代码进行优化:

@echo off
rem Time Calculation
for /F "skip=1 tokens=1-4" %%A in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_LocalTime GET Day^,Hour^,Minute^,Second') do (
set Day=%%A
set Hour=%%B
set Minute=%%C
set Second=%%D
)
set /A TimeStart=Day * 86400 + Hour * 3600 + Minute *60 + Second

@echo on
%SystemRoot%\System32\ping.exe 8.8.8.8 -n 11
@echo off

for /F "skip=1 tokens=1-4" %%A in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_LocalTime GET Day^,Hour^,Minute^,Second') do (
set Day=%%A
set Hour=%%B
set Minute=%%C
set Second=%%D
)
set /A TimeEnd=Day * 86400 + Hour * 3600 + Minute *60 + Second

set /A TimeDiff=TimeEnd - TimeStart
set /A DiffSec=TimeDiff %% 60
set /A TimeDiff=(TimeDiff - DiffSec) / 60
set /A DiffMin= TimeDiff %% 60
set /A DiffHrs=(TimeDiff - DiffMin) / 60

set "DiffSec=0%DiffSec%"
set "DiffSec=%DiffSec:~-2%"
set "DiffMin=0%DiffMin%"
set "DiffMin=%DiffMin:~-2%"
set "DiffHrs=0%DiffHrs%"
set "DiffHrs=%DiffHrs:~-2%"

echo Time needed for orders deletion: %DiffHrs%:%DiffMin%:%DiffSec%


要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。


set /A
echo /?
for /?
ping /?
rem /?
set /?
wmic /?

关于batch-file - 具有常量的变量的批处理文件比较失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42435648/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com