问题
How do I get "FINDSTR" find a value between a specified range ? I set the "string": "20141001" and "20141030" . If within the *.TXT file exists "20141017", should return the "ERRORLEVEL" = 0.
EXEMPLE:
@echo off
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
回答1:
Use
findstr
with a regexp that catches only the strings you want:findstr /r "\<201410[0-3][0-9]\>"
Of course this is a simplified regexp that will also catch
31
of October (which is bad) and the invalid00
and39
(but if your file contains only valid dates it's not a problem), so you'll have to write several regexps for each 10 day range.Or generate a list of the dates in a loop, write them to a file and use that file in
findstr
. Here's an example that generates two date scopes:20141001 20141030
and20151001 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
The above solution will [erroneously] catch the numbers inside other bigger numbers like 22222220141001 so if this is undesirable here's a much slower but more reliable version:
@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
回答2:
I'm not aware of a good FINDSTR solution. But there is a simple solution using JREPL.BAT - a regular expression text processing utility that runs natively on any Windows machine from XP onward. It is pure script (hybrid batch/JScript) that does not require any 3rd party executables.
The solution uses a simple regular expression, coupled with a tiny bit of custom JScript code provided on the command line.
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
来源:https://stackoverflow.com/questions/33177951/how-to-findstr-seek-an-occurrence-within-a-numerical-range-specified-in-all-txt