【问题标题】:How can I tell if a Batch variable is text or a number?如何判断 Batch 变量是文本还是数字?
【发布时间】:2014-08-22 14:55:09
【问题描述】:

这是一件非常简单的事情,我很难弄清楚。

我有一个脚本。它将日期分解为单独的变量,如下所示:

for /f "tokens=1,2,3,4 delims=/ " %%a in ( 'DATE /T' ) do set DD=%%a&set MM=%%b&set YYYY=%%c
for /f "tokens=1,2,3,4 delims=:." %%e in ("%time%") do set HH=%%e&set MI=%%f&set SS=%%g

这在 cmd 中很棒!直到我使脚本成为计划任务。当它是计划任务时,DATE /T 中的第一个标记是日期名称(如星期一、星期二、星期三等)。问题是我需要它是日期,而不是日期。

对我来说,这应该是一个简单的 if 语句来检查 %%A 是否是一个数字,但我不知道如何检查这个。我在这里浏览了旧博客和问题,但我发现是空的。有人可以帮忙吗?

【问题讨论】:

    标签: windows batch-file cmd scheduled-tasks windows-server-2012


    【解决方案1】:

    您可以尝试将变量设置为数字:

    set /a x=TUE
    id "%x%"="0" echo this is not a number
    

    但我建议使用独立于语言的解决方案:

    for /f %%i in ('wmic os get localdatetime^|find "."') do set x=%%i
    set YYYY=%x:~0,4%
    set MM=%x:~4,2%
    set DD=%x:~6,2%
    set HH=%x:~8,2%
    set MI=%x:~10,2%
    set SS=%x:~12,2%
    

    或者,如果您不介意使用其他变量名和缺少前导 0(例如 8 代表 August 而不是 08):

    for /f %%i in ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /value ^|find "="') do set %%i
    

    得到

    Day=22
    Hour=17
    Minute=19
    Month=8
    Second=12
    Year=2014
    

    【讨论】:

      【解决方案2】:

      当代码可以在不同的机器上运行时,日期变量是不可靠的。

      此代码的前四行将在 XP Pro 及更高版本中为您提供可靠的 YY DD MM YYYY HH Min Sec 变量。

      @echo off
      for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
      set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
      set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
      
      set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%" & set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"
      echo datestamp: "%datestamp%"
      echo timestamp: "%timestamp%"
      echo fullstamp: "%fullstamp%"
      pause
      

      【讨论】:

        【解决方案3】:

        回答你原来的场景让你思考一个字符串是文本还是数字 - 始终最好使用 wmic 代码来确定 Windows 中的日期和时间,因为它返回 ISO 标准中的值,并且无论区域设置如何,它都是相同的。下面是代码。

        for /f %%x in ('wmic os get localdatetime ^| findstr /b [0-9]') do set TS=%%x
        
        set yyyy=%TS:~0,4%
        set mm=%TS:~4,2%
        set dd=%TS:~6,2%
        set hh=%TS:~8,2%
        set min=%TS:~10,2%
        set timestamp=%dd%-%mm%-%yyyy%_%hh%-%min%
        echo %timestamp%
        

        在这里回答您的问题 - 下面可能会帮助您了解如何查找变量是文本或数字。

        @echo off   
        setlocal enabledelayedexpansion 
        for /f %%i in (input.txt) do (  
            (echo.%%i | findstr /i [a-z] >nul) || (echo.%%i | findstr /i [0-9] >nul) && echo.%%i is a number
            (echo.%%i | findstr /i [0-9] >nul) || (echo.%%i | findstr /i [a-z] >nul) && echo.%%i is a text
            (echo.%%i | findstr /i [0-9] >nul) && (echo.%%i | findstr /i [a-z] >nul) && echo.%%i is a text and number
        )   
        

        示例(测试)输出 -

        D:\Scripts>type input.txt
        1234
        abcd
        123abc
        Hello world
        12345
        welcome
        we1c0me
        
        D:\Scripts>draft.bat
        1234 is a number
        abcd is a text
        123abc is a text and number
        Hello is a text
        12345 is a number
        welcome is a text
        we1c0me is a text and number
        

        干杯,G

        【讨论】:

          【解决方案4】:

          首先,我怀疑您遇到了区域设置差异。您的计划任务可能在具有不同设置的不同帐户中运行。 (从 CMD 运行时,我首先在我的系统上获取日期名称。)即使你去掉了星期几,你也可能对数字的顺序有问题(例如,我的是 MM-DD-YYYY)。

          也就是说...如果您只想跳过星期几的文本,那么对您的脚本进行绝对最简单的更改如下:

          for /f "tokens=1,2,3,4 delims=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/ " %%a in ('DATE /T') do set DD=%%a&set MM=%%b&set YYYY=%%c
          for /f "tokens=1,2,3,4 delims=:." %%e in ("%time%") do set HH=%%e&set MI=%%f&set SS=%%g
          

          这只是将所有(英文)字母字符视为分隔符,因此 FOR 命令会愉快地跳过它们。

          更直接地回答你的问题:如果你想检查一个值是否是一个数字,你可以尝试这样的事情:

          set VAL_TO_TEST=...
          set /a VAL=%VAL_TO_TEST%+0
          if "%VAL%"=="%VAL_TO_TEST%" echo VAL_TO_TEST is a number
          

          这依赖于 SET 相当松散的表达式解析(它通常将无法解析的任何内容视为零)。如果输入字符串的格式不正确(额外的空格等),您可能会遇到这种技术的问题,但这里不会出现这种情况。

          【讨论】:

            【解决方案5】:
            set "yyyy=" & for /f "tokens=1-6 delims=/: " %%a in (
                'robocopy "|" . /njh /nocopy /l'
            ) do if not defined yyyy (
                set "yyyy=%%a" & set "mm=%%b" & set "dd=%%c" 
                set "hh=%%d" & set "nn=%%e" & set "ss=%%f"
            )
            
            echo %yyyy% %mm% %dd% %hh% %nn% %ss%
            

            这使用robocopy 生成错误并从输出中检索日期/时间

            【讨论】:

            • 很高兴知道这一点,但这可能会在没有内置 robocopy 的旧系统(尤其是 windows 2003 服务器)上失败。
            • @gbabu,你是对的。我在这里包含这个是因为 windows 2012 标签。无论如何,在可免费下载的 Windows Server 2003 资源工具包工具中,Microsoft 提供了适用于 windows 2003 或 XP 的 robocopy
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-03-16
            • 2021-09-24
            • 2011-09-12
            • 1970-01-01
            • 1970-01-01
            • 2013-01-11
            • 2011-10-01
            相关资源
            最近更新 更多