Llor1s
Llor1s

Reputation: 59

Select info from txt in bat file

There is a text file that stores a log of processed files in the following format:

Name: kn-25.txt Date: 01.02.2013 Time: 14:50

The task is to write a batch file which will make a selection from this file for a given month (mm) and year (yyyy) into the file result.txt.

@echo off
chcp 1251 >nul
setlocal EnableDelayedExpansion
echo Введіть початковий файл:  
set /p in_file=%~nx1
if not exist %in_file% goto end

del D:\result.txt
set /a count=0
set /a con=0
set /a min=101
set /p month=Введіть місяць: 
if [%month%] == [] goto end 
set /p year=Введіть рік: 
if [%year%] == [] goto end 
goto start

:start
if count equ 0 (
set /a con=0 
) else (
set /a con=0-!count!
)
for /f "tokens=*" %%i in (%in_file%) do (
    for /f "tokens=1-6" %%a in ("%%~i") do (
        for /f "delims=. tokens=1-3" %%u in ("%%~d") do (
            if "%%v"=="%month%" if "%%w"=="%year%" (
                 set /a con=!con!+1 
                     if "%%u" leq "!min:~-2!" (
                         set /a min1=!min!-1
                         if "%%u" neq "!min1:~-2!" (
                            set /a count=!count!+1                    
                            echo !count!. %%i>>D:\result.txt
                    )
                )
            )       
        )   
    )
)

if %con% neq %count% (
set /a min=!min!+1
goto start
) else (
type D:\result.txt
echo 
@pause
endlocal
exit /B 
)

:end
echo Ви не ввели параметр!
echo   
@pause
endlocal
exit /B 

I wrote this code, but got an error:

Cannot find the file Name:.

Any suggestions?

Note: information in the generated file must be sorted by date

Example:

Initial file content:

Name: kn-25.txt Date: 07.03.2013 Time: 14:50

Name: kn-26.txt Date: 02.03.2013 Time: 23:50

Name: MyFil.txt Date: 03.08.2012 Time: 12:00

Name: ca-21.txt Date: 28.03.2013 Time: 01:00

Name: ca-25.txt Date: 01.30.2012 Time: 10:05

Input: 03.2013

Output:

Name: kn-26.txt Date: 02.03.2013 Time: 23:50

Name: kn-25.txt Date: 07.03.2013 Time: 14:50

Name: ca-21.txt Date: 28.03.2013 Time: 01:00

Upvotes: 2

Views: 501

Answers (4)

aschipfl
aschipfl

Reputation: 34909

The following code uses a temporary file containing the lines from the input file filtered by the given date information (month and year), but with each line prefixed by year, month and day as well as the time value, which allows easy alphabetic sorting that is fine for your fixed-width date/time formats:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "IN_FILE=%~1"
set "OUT_FILE=D:\result.txt"
set "TMP_FILE=%TEMP%\%~n0_%RANDOM%.tmp"
set "MONTH=03"
set "YEAR=2013"

rem /* Filter lines for given month and year, then write them
rem    to temporary file, preceded by year, month, date and `:`: */
> "%TMP_FILE%" (
    for /F usebackq^ delims^=^ eol^= %%L in ("%IN_FILE%") do (
        for /F "tokens=3-5 delims=:" %%D in ("%%L") do (
            for /F "tokens=1-3 delims=. " %%A in ("%%D") do (
                if "%%B" == "%MONTH%" if "%%C" == "%YEAR%" (
                    echo(%%C%%B%%A%%E%%F:%%L
                )
            )
        )
    )
)
rem /* Sort content of temporary file, remove prefix
rem    up to the (first) `:` and write to result file: */
> "%OUT_FILE%" (
    for /F "tokens=1* delims=:" %%E in ('sort "%TMP_FILE%"') do (
        echo(%%F
    )
)
rem // Clean up temporary file:
del "%TMP_FILE%"

endlocal
exit /B

Upvotes: 0

lit
lit

Reputation: 16236

If you are on a supported Windows machine, it will have PowerShell on it. Here is one way to do it. This assumes that the date is in DD.MM.YYYY format.

Since it has already parsed out the date and time with a regex, it creates a [DateTime] to associate with the log file line. It then uses this [DateTime] to sort the file, but only outputs the log file line.

[CmdletBinding()]
param (
    [Parameter(Mandatory=$true,Position=0)]
    [string]$LogFile
    ,[Parameter(Mandatory=$true,Position=1)]
    [int]$Year
    ,[Parameter(Mandatory=$true,Position=2)]
    [int]$Month
)

Get-Content -Path $LogFile |
    ForEach-Object {
        if ($_ -match 'Name: .* Date: ((\d*).(\d*).(\d*)) Time: ((\d*):(\d*))') {
            #$Matches
            $fday = [int]$Matches[2]
            $fmonth = [int]$Matches[3]
            $fyear = [int]$Matches[4]
            $fhour = [int]$Matches[6]
            $fminutes = [int]$Matches[7]
            if (($fmonth -eq $Month) -and ($fyear -eq $Year)) {
                [PSCustomObject]@{
                    Line = $_
                    Timestamp = Get-Date -Year $fyear -Month $fmonth -Day $fday `
                        -Hour $fhour -Minute $fminutes -Second 0
                }
            }
        }
    } |
    Sort-Object -Property Timestamp |
    ForEach-Object { $_.Line }

Invoke it using the following command. If you do not provide the parameters, PowerShell will prompt for them. That is like using SET /P in a cmd.exe bat file script.

.\logparse.ps1 -LogFile '.\logparse.in.txt' -Year 2013 -Month 2

If you must run it from a cmd.exe shell, use:

powershell -NoLogo -NoProfile -File ".\logparse.ps1"

Upvotes: 0

Stephan
Stephan

Reputation: 56180

a slightly different approach (slower than the other ones, but working as intended):

@echo off
setlocal EnableDelayedExpansion

set in_file=t.txt
set month=03
set year=2013

(for /l %%a in (100,1,131) do (
  set "day=%%a"
  findstr "!day:~-2!.%month%.%year%" %in_file% 
))>result.txt

Upvotes: 0

SNR
SNR

Reputation: 772

For sorting we ignore the first 22 characters sort command.

@echo off
chcp 1251 >nul
setlocal EnableDelayedExpansion
echo Введіть перший параметр: 
set /p in_file=%~f1
if not exist %in_file% goto end


set /p month=Введіть місяць:
if [%month%] == [] goto end
set /p year=Введіть рік:
if [%year%] == [] goto end 

findstr /C:"%month%.%year%" %in_file% | sort /+22 > D:\result.txt

type D:\result.txt 
pause
exit /B

:end
echo Ви не ввели параметр! 
pause
exit /B

We can use findstr /O if we want an offset on each line.

Upvotes: 0

Related Questions