【问题标题】:Batch file setting variable in if/else statement in For LoopFor循环中if/else语句中的批处理文件设置变量
【发布时间】:2013-05-29 19:51:55
【问题描述】:

我正在尝试创建一个批处理文件,为每个文件生成一个自定义 AVIsynth 脚本。现在,批处理文件设置为从视频文件所在的文件夹中执行。我需要做的是获取文件的创建时间以生成时间码刻录。获取所需的信息没有问题。但是,如果文件是在下午创建的,我需要它在 24 小时内。比如 2pm 需要显示为 14。

我有一个有效的 if 语句,它创建一个 newth 变量,如果需要,它会增加 12。但是,如果它不需要它,变量仍然存在。在循环的每次后续迭代中,变量都不会改变。

我的例子。我有两个文件,第一个是在下午 2 点创建的,另一个是在下午 12 点创建的。首先读取 2pm 文件,newth 变量变为 14。到目前为止一切顺利。在下一个文件中,newth 变量应变为 12,但仍为 14。如何解决此问题?

@Echo Off & CLS
SetLocal EnableDelayedExpansion
For /F %%a In ('dir *.mpg /b') Do (
    ECHO Processing "%%a"
    echo %%~ta
    set time=%%~ta
    set th=!time:~11,2!
    set tm=!time:~14,2!
    set era=!time:~17,2!
    echo !era!
    if "!era!"=="PM" (
        if !th! LSS 12 ( set /a newth=!th!+12 )
    ) else ( set /a newth=!th!)

    echo !newth!
    echo //AviSynth Test Script >scripts/%%a.avs
    echo DirectshowSource^("%%~fa"^)>>scripts/%%a.avs
    echo LanczosResize^(720,400^) >>scripts/%%a.avs
    echo ShowSMPTE^(^) >>scripts/%%a.avs

    ECHO Back to Console
    Pause
)

这有点乱,因为我一直在使用echo 进行调试。但希望问题很清楚。

【问题讨论】:

  • 你试过if /i "!era!" == "PM"
  • 谢谢,但这并不能解决我遇到的问题。问题是如果newth 存在于前一个循环中,它不会在else 部分切换回!th!。因此,保持其值与前一次迭代相同。
  • 你的操作系统是什么?还有其他几种方法可以打发时间...
  • aaah...在循环开始时设置set "th=" 以清除它的值
  • 我在 Windows 7 上。我刚刚发现将操作系统时间设置为 24 小时可以解决问题。但是,我希望将文件修改时间缩短到秒,但只能让 cmd 显示小时和分钟。

标签: for-loop batch-file


【解决方案1】:

这是一个使用 Wmic 的方法 - Wmic 在 XP pro 及更高版本中。

@Echo Off & CLS
SetLocal EnableDelayedExpansion
For /F "delims=" %%a In ('dir *.mpg /b') Do (
    ECHO Processing "%%a"

    set "file=%cd%\%%a"
    set "file=!file:\=\\!"
    WMIC DATAFILE WHERE name="!file!" get creationdate|find ".">file.tmp
    for /f %%a in (file.tmp) do set dt=%%a
    set tm=!dt:~8,2!:!dt:~10,2!:!dt:~12,2!
    del file.tmp
    echo !tm!
    echo //AviSynth Test Script >scripts/%%a.avs
    echo DirectshowSource^("%%~fa"^)>>scripts/%%a.avs
    echo LanczosResize^(720,400^) >>scripts/%%a.avs
    echo ShowSMPTE^(^) >>scripts/%%a.avs

    ECHO Back to Console
    Pause
)

【讨论】:

    【解决方案2】:

    您的代码存在一些问题。最主要的是这个序列

    if "!era!"=="PM" (
        if !th! LSS 12 ( set /a newth=!th!+12 )
    ) else ( set /a newth=!th!)
    

    您的第一个文件时间为“02:xx PM”
    th=02、era=PM,所以set /a newth=02+12 设置为newth=14

    第二个文件时间为“12:xx PM”
    th=12、era=PM,所以 - 什么也不做,因为 !th! LSS 12 没有 else 操作

    因此,newth 仍为 14。

    那么 - 解决方法是什么?由于您不再使用newth,因此我们不能肯定地说,但您似乎想要24 小时格式- 4 位hhmm。

    危险,威尔罗宾逊第 1 时刻:
    您正在处理以 LEADING ZEROES 为主角的数字。一切都很好,除了值是08 或09,这批奇怪地解释为八进制,因为它以0 开头。

    危险,Will Robinson 时刻 2:
    set /a 将抑制前导零,因此 set /a newth=!th! 会将 newth 设置为 7 时间 07:36 AM - 不是 @ 987654342@...

    那么 - 如何克服这一切?

    IF !th!==12 SET th=00
    SET th=!th: =0!
    if "!era!"=="PM" (set /a newth=1!th!+12
     SET newth=!newth:~-2!
    ) else ( set newth=!th!)
    

    这会强制 12 AM 到 00 AM 和 12 PM 到 00 PM
    然后将任何spaces 替换为0(如果您有前导空格,而不是零)
    然后,如果era 是PM,则在2-digit 小时数之前通过串接1 添加100,添加12 并获取最后2 个字符
    否则,只需使用th中的号码

    很遗憾,由于您没有告诉我们您是否在时间格式中使用前导零,所以这有点复杂。然而,不完整的原始计算方法是有问题的。

    DANGER,Will Robinson 第 3 个时刻:
    time 是一个魔法变量 - 你知道what happened to Mickey 当他参与到更好的事情中时独自的。

    如果您批量设置time,则%time% 或!time! 将返回您设置的值。如果不设置,则返回的值为系统时间。 DATE 和许多类似的值也是如此(请参阅提示中的 set /? - 最后有一个列表)

    【讨论】:

      【解决方案3】:

      您可以通过以下方式获取带有秒数的时间戳:

      C:\>powershell -command "& {(gwmi -query """select * from cim_datafile where name = 'C:\\file.txt' """).lastModified;}"
      
      C:\>powershell -command "& {(gwmi -query """select * from cim_datafile where name = 'D:\\other.txt' """).creationdate;}"
      

      我尝试过WMIC,但仍然无法获取时间戳。由于您使用的是 Win7,因此您应该默认安装 powershell。

      【讨论】:

        猜你喜欢
        • 2012-07-30
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 2019-06-20
        • 2016-04-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多