windows - 批处理文件中 for 循环中关系运算符的用法

标签 windows batch-file

我制作了一个批处理文件,它显示当前文件夹中所有可用视频的名称,并询问您要播放哪一个。然后根据您的选择播放该特定视频并将该视频的名称记录到文件“watched.txt”中。所以,基本上我希望“watched.txt”以剧集编号降序记录所有观看过的视频名称。如果以前观看过视频,则不应将其再次记录到文件 Watched.txt 中。

此外,所有视频名称都具有与“Suits.S03Exx.720p”相同的结构,其中只有 xx(即集数)发生变化。 xx 始终是两位整数(如 01、02、03、...、11、...)。

批处理脚本(最后提供)使用 for 循环逐行读取文件“watched.txt”。

下面是“watched.txt”文件的内容:

Suits.S03E10.720p                       
Suits.S03E09.720p                        
Suits.S03E08.720p                         
Suits.S03E07.720p                          
Suits.S03E06.720p                           
Suits.S03E05.720p                            
Suits.S03E04.720p                             
Suits.S03E03.720p                              
Suits.S03E02.720p                               
Suits.S03E01.720p

现在,当我第二次通过批处理文件(文件名:“Suits.S03E08.720p”)播放第 08 集时,它再次被记录到 Watched.txt 中,这不是我想要的。它生成以下“watched.txt”文件:

Suits.S03E08.720p 
Suits.S03E10.720p                          
Suits.S03E09.720p                           
Suits.S03E08.720p                            
Suits.S03E07.720p                             
Suits.S03E06.720p                              
Suits.S03E05.720p                               
Suits.S03E04.720p                                
Suits.S03E03.720p                                 
Suits.S03E02.720p                                  
Suits.S03E01.720p

但是,我期待相同的 Watched.txt,其内容没有任何变化,因为第 08 集之前播放过并且已经存在于其中。

我检查了在监视.txt 操作中使用的临时文件(temp1.txt、temp2.​​txt 和 temp3.txt)(通过注释掉批处理文件中的这些语句以进行测试:del temp1.txt、del temp2 .txt,del temp3.txt)

发现第一个临时文件 temp1.txt 为空。相反,我希望它按照我的批处理文件的逻辑具有以下内容:

Suits.S03E10.720p                       
Suits.S03E09.720p 

发现第二个临时文件 temp2.​​txt 具有以下内容:

Suits.S03E10.720p                        
Suits.S03E09.720p                         
Suits.S03E08.720p                          
Suits.S03E07.720p                           
Suits.S03E06.720p                            
Suits.S03E05.720p                             
Suits.S03E04.720p                              
Suits.S03E03.720p                               
Suits.S03E02.720p                                
Suits.S03E01.720p

相反,根据我的批处理文件的逻辑,我希望 temp2.​​txt 为空。

现在,发现第三个临时文件temp3.txt具有以下内容:

Suits.S03E08.720p 
Suits.S03E10.720p                        
Suits.S03E09.720p                         
Suits.S03E08.720p                          
Suits.S03E07.720p                           
Suits.S03E06.720p                            
Suits.S03E05.720p                             
Suits.S03E04.720p                              
Suits.S03E03.720p                               
Suits.S03E02.720p                                
Suits.S03E01.720p

相反,根据我的批处理文件的逻辑,我希望 temp3.txt 为空。

下面是批处理文件的结束部分(我没有附加完整代码),我正在使用这些输入 justPlayedName=Suits.S03E08.720p & justPlayedNumber=08 (这些输入来自整个批处理的初始部分文件):


break> temp1.txt
break> temp2.txt
break> temp3.txt

setlocal ENABLEDELAYEDEXPANSION 
for /f "tokens=*" %%S in (watched.txt) do (
    set watchedName=%%S
    set watchedNumber= !watchedName:~10,2!
    if !watchedNumber! EQU !justPlayedNumber! ( goto EOFL_2 ) 
    if !watchedNumber! GTR !justPlayedNumber! (
        echo !watchedName! >> temp1.txt
    )
    if !watchedNumber! LSS !justPlayedNumber! (
        echo !watchedName! >> temp2.txt
    )
)
endlocal

type temp1.txt > temp3.txt
echo %justPlayedName% >> temp3.txt
type temp2.txt >> temp3.txt
type temp3.txt > watched.txt
:EOFL_2
del temp1.txt
del temp2.txt
del temp3.txt

pause

有人请告诉我问题出在哪里吗?

最佳答案

您的代码中有几处错误。

set watchedNumber= !watchedName:~10,2!

等号后面的空格也是分配给环境变量watchedNumber的字符串值的一部分。另请参阅:Why is no string output with 'echo %var%' after using 'set var = text' on command line?

if !watchedNumber! EQU !justPlayedNumber!

运算符 EQU 会比较两个字符串,并转换为 32 位有符号整数值(如果可能的话)。这里的问题是像 0809 这样的字符串被解释为无效的八进制整数,而不是十进制数 89 并以 0 开头。因此,至少对于字符串值 0809,此整数比较无法按您的预期进行。另请参阅:Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files 。引用的答案非常详细地解释了命令 IF 如何对使用运算符 EQU 与使用运算符 == 进行比较。

整个代码比必要的更复杂。 Windows 上默认安装了两个可执行文件来查找文件中的字符串:FINDFINDSTR。两者都可用于根据 justPlayedNumber 的字符串值在文件 watched.txt 中搜索类似 Suits.S03E08.720p 的字符串。如果在文件中找不到搜索的字符串,则两个可执行文件都会以 1 退出。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "justPlayedNumber=08"
if not "%~1" == "" (
    for /F delims^=0123456789^ eol^= %%I in ("%~1") do (
        echo "%~1" is not a valid number!
        goto EndBatch
    )
    set "justPlayedNumber=%~1"
)
if "%justPlayedNumber:~1%" == "" set "justPlayedNumber=0%justPlayedNumber%"
set "justPlayedNumber=%justPlayedNumber:~0,2%"

%SystemRoot%\System32\findstr.exe /B /L /C:"Suits.S03E%justPlayedNumber%.720p" "%~dp0watched.txt" >nul 2>nul
if errorlevel 1 (
    echo Suits.S03E%justPlayedNumber%.720p>>"%~dp0watched.txt"
    %SystemRoot%\System32\sort.exe "%~dp0watched.txt" /O "%~dp0watched.txt"
    echo Added Suits.S03E%justPlayedNumber%.720p to file watched.txt.
)

:EndBatch
endlocal

第一行到第一个空行只是为了方便测试用于此任务的接下来的六行。这些行使得可以在不带参数以及第一个参数为 26483952 或无效字符串的情况下运行批处理文件对于仅由数字组成的数字。如果传递的字符串少于或多于两位数,则将其扩展或截断为两位数。

使用完整限定文件名执行外部命令FINDSTR,以在批处理目录中的文件watched.txt中的所有行的开头按字面搜索并区分大小写字符串 Suits.S03E%justPlayedNumber%.720p 的文件,其中 %justPlayedNumber% 之前被 Windows 命令处理器 cmd.exe 替换为两个数字字符串。

如果文件 watched.txt 根本不存在或搜索的字符串不存在,

FINDSTR 将以大于或等于 1 的值退出文件中找到。在这种情况下,搜索字符串将附加到文件中,相应地,创建的文件中的搜索字符串根本不存在。

然后使用命令SORT对文件中的行进行排序。这并不是真正需要的,但可以使用户在文本编辑器或其他应用程序中查看此文本文件时更容易阅读这些行。

阅读有关 Using command redirection operators 的 Microsoft 文章,了解 >>>nul 以及 2>nul 的说明。

要了解所使用的命令及其工作原理,请打开 command prompt 窗口,在其中执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

  • 回显/?
  • endlocal/?
  • findstr/?
  • 对于/?
  • 转到/?
  • 如果/?
  • setlocal/?
  • 排序/?

关于windows - 批处理文件中 for 循环中关系运算符的用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59704125/

相关文章:

c - 在 Chrome 的 NPAPI 窗口插件中使用 Windows raw_input

batch-file - 当文件结构中存在文件时,如何使 Windows 批处理文件退出?

.net - 如何在 PowerShell 中引用 UWP 类

C++ 应用程序在崩溃后运行缓慢(MSVS、Win8 x64)

windows - 使用 7-Zip 压缩和删除同一文件

windows - 如何将主机名存储在 .bat 文件的变量中?

batch-file - 批处理文件-搜索任何包含文本的文件夹,如果找不到任何文件夹,则继续

batch-file - 连接两个字符串 'present working directory' 和 'app.exe' 文件名以构建绝对路径

c++ - 哪个文件在 Windows Embedded Compact 7.0 上配置缓存?

c++ - 以另一个用户身份运行程序