Reputation: 59
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
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
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
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
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