Reputation: 1
I had to write a .Bat file in MS-Command prompt to extract 2 specific strings "Username" and "last login time" from a folder having say a 100 log files and each of these log file has these 2 things. The output must be printed to a csv file report to be saved somewhere.
echo Processing user's last login time. Please wait...
S:
cd log_files
for %G IN (*.txt) do (findstr /i "Username: Log-In" "%G" >> S:\Sourav\GIS_Login_Time.txt)
echo Execution Complete.
echo Output file created in C:\data folder.
pause
The output file (in txt format) is like below :
*** OS Username: ADIELA
*** GIS Username: adiela ( Laura Adie - Horizons, Bullion )
*** Log-In Time: 21/07/2014 06:37:20
*** OS Username: allanj1
*** GIS Username: allanj ( Jim Allan - Shared access Lomond House )
*** Log-In Time: 17/12/2014 11:44:22
...
Could you please advise how to modify the output (which goes to a text file now) to go into a csv file? The output file must have 3 columns. 1)OS Username 2) GIS USername 3) Log-In time. I would greatly appreciate if I could get some valuable suggestions for this. Thank you in advance :)
Upvotes: 0
Views: 11575
Reputation: 130919
Another perfect problem for my JREPL.BAT utility - a hybrid JScript/batch script that performs a regular expression search and replace on text. JREPL.BAT is pure script that runs natively on any Windows machine from XP onward.
Assuming every file has all three entries in the same order (though not necessarily consecutively), then this one liner will create "output.csv". Note that I used line continuation just so the code is easier to read.
type *.txt 2>&1 | jrepl ^
"OS Username:\s*(.*?)$[\s\S]*?GIS Username:\s*(.*?)$[\s\S]*?Log-In Time:\s*(.*?)$" ^
"'\x22'+$1+'\x22,\x22'+$2+'\x22,\x22'+$3+'\x22'" ^
/m /jmatch /o output.csv
-- OUTPUT using your example text --
"ADIELA","adiela ( Laura Adie - Horizons, Bullion )","21/07/2014 06:37:20"
"allanj1","allanj ( Jim Allan - Shared access Lomond House )","17/12/2014 11:44:22"
If you truly want just the GPS username, without the parenthesized info, then you don't need quotes because your data no longer contains commas:
type *.txt 2>&1 | jrepl ^
"OS Username:\s*(.*?)$[\s\S]*?GIS Username:\s*(.*?)\s[\s\S]*?Log-In Time:\s*(.*?)$" ^
"$1+','+$2+','+$3" ^
/m /jmatch /o output.csv
-- OUTPUT --
ADIELA,adiela,21/07/2014 06:37:20
allanj1,allanj,17/12/2014 11:44:22
It is easy to add the header line that lists the column names:
type *.txt 2>&1 | jrepl ^
"OS Username:\s*(.*?)$[\s\S]*?GIS Username:\s*(.*?)\s[\s\S]*?Log-In Time:\s*(.*?)$" ^
"$1+','+$2+','+$3" ^
/jbeg "output.WriteLine('OS Username,GIS Username,Login Time')" ^
/m /jmatch /o output.csv
-- OUTPUT --
OS Username,GIS Username,Login Time
ADIELA,adiela,21/07/2014 06:37:20
allanj1,allanj,17/12/2014 11:44:22
Upvotes: 2
Reputation: 56238
This builds your csv directly from the source files (without a temporary file):
@echo off
setlocal enabledelayedexpansion
REM write first line:
echo OSUser;GISUser;LoginTime >out.csv
REM for every .txt file:
for %%i in (*.txt) do (
REM add the three strings:
set "x="
for /f "tokens=1,* delims=:" %%a in ('findstr "Username Log-In" %%i') do set x=!x!%%b;
REM delete any "two consecutive spaces":
set x=!x: =!
REM delete TABs ( it's a TAB between : and = ):
set x=!x: =!
REM delete last ; (if it disturbes you):
set x=!x:~0,-1!
REM write it to the file:
echo !x!>>out.csv
)
Upvotes: 0
Reputation: 6588
This was a good one. Here is how I solved it:
@ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
SET SourceFile="C:\SourceFile.txt"
SET OutputFile="C:\List.txt"
SET TempFile1="%TEMP%\1.txt"
SET TempFile2="%TEMP%\2.txt"
SET TempFile3="%TEMP%\3.txt"
REM Initialize files.
ECHO Header>%TempFile1%
ECHO Header>%TempFile2%
ECHO Header>%TempFile3%
IF EXIST %OutputFile% DEL %OutputFile%
REM Build a list of each value.
FOR /F "usebackq tokens=1,* delims=:" %%A IN (`FINDSTR /L "OS" %SourceFile%`) DO ECHO %%B>>%TempFile1%
FOR /F "usebackq tokens=1,* delims=:" %%A IN (`FINDSTR /L "GIS" %SourceFile%`) DO ECHO %%B>>%TempFile2%
FOR /F "usebackq tokens=1,* delims=:" %%A IN (`FINDSTR /L "Log-In" %SourceFile%`) DO ECHO %%B>>%TempFile3%
REM All temp files should have the same number of entries.
REM Concatenate them with a comma.
SET Skip=1
:ProcessLine
REM Keep going until we find the first empty entry.
REM This means we reached the end of the list.
SET "OSUserName="
SET "GISUserName="
SET "LogInTime="
REM Only set the first line.
FOR /F "usebackq tokens=* skip=%Skip% delims= " %%A IN (%TempFile1%) DO IF "!OSUserName!"=="" SET OSUserName=%%A
FOR /F "usebackq tokens=* skip=%Skip% delims= " %%A IN (%TempFile2%) DO IF "!GISUserName!"=="" SET GISUserName=%%A
FOR /F "usebackq tokens=* skip=%Skip% delims= " %%A IN (%TempFile3%) DO IF "!LogInTime!"=="" SET LogInTime=%%A
ECHO %OSUserName%
REM Check for the end of the list.
IF "%OSUserName%"=="" GOTO Finish
REM Add to the output.
ECHO %OSUserName%,%GISUserName%,%LogInTime%>>%OutputFile%
REM Increment counter and loop.
SET /A Skip=%Skip%+1
GOTO ProcessLine
:Finish
REM Cleanup.
IF EXIST %TempFile1% DEL %TempFile1%
IF EXIST %TempFile2% DEL %TempFile2%
IF EXIST %TempFile3% DEL %TempFile3%
ENDLOCAL
Upvotes: 0