2015-10-16 90 views
-2

如何获得“FINDSTR”查找指定范围内的值? 我设置了“字符串”:“20141001”和“20141030”。如果内* .TXT文件存在 “20141017”,应该返回 “ERRORLEVEL”= 0如何FINDSTR在目录中的所有TXT中指定的数值范围内查找出现?

为例:

关闭@echo

SET DATE_STA=20141001 
SET DATE_END=20141030 

echo Looking for all the files in the folder 
echo within the range from %DATE_STA% to %DATA_END% ... 
echo. 

:FINDING 
findstr /r "%DATE_STA% to %DATA_END%" C:\Folder\*.txt 
IF %ERRORLEVEL%==0 (
goto OKAY) else (
goto FAIL 
) 

:OKAY 
cls 
echo. 
echo Located file that contains a value in the specified range. 
echo. 
pause 
exit 

:FAIL 
cls 
echo. 
echo Any file located in this folder.. 
echo. 
pause 
exit 
+0

我没有看到你在批处理文件中的任何地方使用'FINDSTR'。还请提供您已经完成的研究,以了解您的位置。 – zealoushacker

+0

'findstr'不能进行数字检查,它搜索其他字符* * – aschipfl

+1

'findstr'命令不能找到指定范围之间的字符串“。每个字符串都必须单独测试才能做到这一点:'if!value! geq%DATE_STA%if!value! leq%DATA_END%goto OKAY',但我们需要知道文件的格式才能编写解决方案。您可以使用'findstr/R“201410 ..”'查找与2014年10月相对应的日期字符串,但这会返回包含这些日期的_complete lines_,而不仅仅是日期字符串!当然,除非每个文件行只包含一个日期(我们需要知道文件的格式)... – Aacini

回答

2
  • 使用findstr用正则表达式是catches only the strings你想:

    findstr /r "\<201410[0-3][0-9]\>" 
    

    当然,这是一个简单的正则表达式是西港岛线l还会捕获10月份的(这很糟糕)的31以及无效的0039(但是如果您的文件只包含有效日期,这不是问题),因此您必须为每10天范围编写几个正则表达式。

  • 或者在循环中生成日期列表,将它们写入文件并使用findstr中的该文件。下面是产生两个日期范围的示例:20141001 2014103020151001 20151030

    @echo off 
    del "%temp%\datespan.txt" >nul 2>&1 
    call :makeDates 20141001 20141030 "%temp%\datespan.txt" 
    call :makeDates 20151001 20151030 "%temp%\datespan.txt" 
    findstr /g:"%temp%\datespan.txt" /s C:\Folder\*.txt 
    del "%temp%\datespan.txt" 
    pause 
    exit /b 
    
    :makeDates 
        setlocal enableDelayedExpansion 
        set "date1=%1" & set "date2=%2" & set "dateFile=%3" 
        set "y1=!date1:~0,4!" & set "m1=1!date1:~4,2!" & set "d1=1!date1:~6,2!" 
        set "y2=!date2:~0,4!" & set "m2=1!date2:~4,2!" & set "d2=1!date2:~6,2!" 
        set /a m1-=100, d1-=100, m2-=100, d2-=100 
        call :dateCalcLeap & call :dateCalcMonth 
        :dateNext 
         set "m=0!m1!" & set "d=0!d1!" & set "ymd=!y1!!m:~-2!!d:~-2!" 
         if !ymd! GTR !date2! endlocal & exit /b 
    
         echo !ymd!>>!dateFile! 
    
         set /a d1+=1 & if !d1! GTR !mDays! (
          set "d1=1" & set /a m1+=1 & call :dateCalcMonth 
          if !m1! GTR 12 set "m1=1" & set /a y1+=1 & call :dateCalcLeap 
         ) 
         goto dateNext 
        :dateCalcMonth 
         if !m1!==2 (set/a mDays=28+leapYear) else (set/a mDays="31-(m1-1) %% 7 %% 2") 
         exit /b 
        :dateCalcLeap 
         set leapYear=0 
         set /a y4=y1 %% 4 & if !y4!==0 (
          set /a y100=y1 %% 100 & if not !y100!==0 set leapYear=1 
          set /a y400=y1 %% 400 & if !y400!==0 set leapYear=1 
         ) 
         exit /b 
    

    将上述溶液将[误]赶上其他更大的号码内的号码,如22222220141001因此,如果这是不希望这里有一个慢得多,但更可靠的版本:

    @echo off 
    del "%temp%\datespan.txt" >nul 2>&1 
    call :makeDates 20141001 20141030 "%temp%\datespan.txt" 
    call :makeDates 20151001 20151030 "%temp%\datespan.txt" 
    findstr /g:"%temp%\datespan.txt" /s C:\Folder\*.txt 
    del "%temp%\datespan.txt" 
    pause 
    exit /b 
    
    :makeDates 
        setlocal enableDelayedExpansion 
        set "date1=%1" & set "date2=%2" & set "dateFile=%3" 
        set "y1=!date1:~0,4!" & set "m1=1!date1:~4,2!" & set "d1=1!date1:~6,2!" 
        set "y2=!date2:~0,4!" & set "m2=1!date2:~4,2!" & set "d2=1!date2:~6,2!" 
        set /a m1-=100, d1-=100, m2-=100, d2-=100 
        call :dateCalcLeap & call :dateCalcMonth 
        :dateNext 
         set "m=0!m1!" & set "d=0!d1!" & set "ymd=!y1!!m:~-2!!d:~-2!" 
         if !ymd! GTR !date2! endlocal & exit /b 
    
         echo \^<!ymd!\^>>>!dateFile! 
    
         rem The next three lines catch embedded dates like abc20141001, 10_20141001_22 
         echo [^^^^0-9]!ymd![^^^^0-9]>>!dateFile! 
         echo [^^^^0-9]!ymd!\^>>>!dateFile! 
         echo \^<!ymd![^^0-9]>>!dateFile! 
    
         set /a d1+=1 & if !d1! GTR !mDays! (
          set "d1=1" & set /a m1+=1 & call :dateCalcMonth 
          if !m1! GTR 12 set "m1=1" & set /a y1+=1 & call :dateCalcLeap 
         ) 
         goto dateNext 
        :dateCalcMonth 
         if !m1!==2 (set/a mDays=28+leapYear) else (set/a mDays="31-(m1-1) %% 7 %% 2") 
         exit /b 
        :dateCalcLeap 
         set leapYear=0 
         set /a y4=y1 %% 4 & if !y4!==0 (
          set /a y100=y1 %% 100 & if not !y100!==0 set leapYear=1 
          set /a y400=y1 %% 400 & if !y400!==0 set leapYear=1 
         ) 
         exit /b 
    
+0

恐怕这也会匹配'20141031' ... – aschipfl

+0

是的,* simple * regexp是不够的。我添加了另一个解决方案。 – wOxxOm

+0

如果数字(日期)嵌入到较大数字中,则两个“解决方案”都将失败。例如,120141001会给出误报。 – dbenham

1

我不知道一个好的FINDSTR解决方案。但是有一个简单的解决方案,使用JREPL.BAT - 一个正常表达式文本处理工具,可以在XP以后的任何Windows机器上本机运行。它是纯脚本(混合批处理/ JScript),不需要任何第三方可执行文件。

该解决方案使用简单的正则表达式,再加上在命令行中提供的一小部分自定义JScript代码。

for /r %%F in (.) do @type "%%F\*.txt" 2>nul | jrepl "\d{8,}" "($0>=20141001 && $0<=20141030) ? $0 : false" /jmatch >nul && echo FOUND || echo NOT FOUND 
+0

这也会捕获'abc20141001xyz'这可能是一件好事。此行为可以通过'findstr'模拟,方法是添加'[^ 0-9] 20141001 [^ 0-9]','[^ 0-9] 20141001 \>','\ <20141001 [^ 0-9] '除了'\ <20141001\>'之外还有字符串文件,所以'findstr'也可以处理这种情况,因此是一个同样可行的解决方案,它仍然具有可完全嵌入的好处(尽管当然JREPL是一件非常好的事情在电脑上)。 – wOxxOm

+0

还应该注意的是,如果有很多文件的*巨大*数量不是日期(比如'1','55'等等),这个解决方案将比findstr慢,因为它执行提供的比较每个号码上都有代码。使用更复杂的正则表达式可能很容易解决。 – wOxxOm

+0

@wOxxOm - 自定义JScript的调用非常快,而更复杂的正则表达式需要更多自己的处理。我不确定额外的正则表达式处理会比我的JScript中的简单数字比较更快。但我确实继续编辑正则表达式以排除小于8位数的数字。 – dbenham

相关问题