need to extarct partial string from a line in log file. I want to read a entries in log file, here is an example:
Thu 08/29/2019 10:46:43.22 setup.bat USB REIMAGE - WinPE reimage of .wim END
I want to extract only day, date and time
I have tried for loop to extract and it doesnot help me
For /F "UseBackQ Delims==" %%A In ("R:\reimage.log") Do Set "lastline=%%A"
IF "%lastline%" == "USB REIMAGE - WinPE reimage of"(
set lastline=!line:~0,4!
echo "The last reimage performed by installer was on %lastline%"
pause
)
The example I gave in the comment was to show how we use tokens. Something like this should do what you want though:
#echo off
for /f "tokens=1-3" %%i in ('type R:\reimage.log ^| findstr /I "USB REIMAGE - WinPE"') do echo %%i %%j %%k
Related
I have a batch file which runs a python script. The python script after completion sends a number like shown below:
I need my batch file to read its own output as it runs and then use this (the number 3 shown in figure below to do some processing
Is this possible with batch?
EDITED FOR CLARITY:
I want to have a script which uses "net use" command.
The output from this specific command is as shown below... which will be printed to cmd window in which script is running ! Now I want my script to read this output ..like if a certain address is found in the already mapped drives list it will do something..like unmap the drive
I don't understand quite well what your purpose is, what has to do python to do with capture the net use command output?
As a rule of thumb, to capture any command output, you must use a for loop (i.e. here capturing clipboard content using powershell
rem get clipboard content into variable
set "psCmd=powershell -Command "add-type -an system.windows.forms; [System.Windows.Forms.Clipboard]::GetText()""
for /F "usebackq delims=" %%# in (`%psCmd%`) do set "clipContent=%%#"
So, in order to grab the output of net use
#echo off
for /f "skip=6 tokens=2,3" %%a in ('net use') do (
echo/%%a | find ":">NUL && echo/Drive letter %%a - Remote name %%b
)
exit/B
But, I suggest that you better use wmic (following two are similar)
#echo off
for /f "useback skip=1 tokens=1,2" %%a in (`"wmic path Win32_LogicalDisk Where DriveType="4" get DeviceID, ProviderName"`) do (
echo/%%a | find ":">NUL && echo/Drive letter %%a - Remote name %%b
)
exit/B
or
#echo off
for /f "useback skip=1 tokens=1,2" %%a in (`"wmic path Win32_MappedLogicalDisk get DeviceID, ProviderName"`) do (
echo/%%a | find ":">NUL && echo/Drive letter %%a - Remote name %%b
)
exit/B
Since, you may add the /node:"some_other_computer_name" switch to wmic and may list mapped drives from any computer on the net, i.e
#echo off
for /f "useback skip=1 tokens=1,2" %%a in (`"wmic /node:"hp-ml110" path Win32_MappedLogicalDisk Where DriveType="4" get DeviceID, ProviderName"`) do (
echo/%%a | find ":">NUL && echo/Drive letter %%a - Remote name %%b
)
exit/B
Hope it helps.
This information below is contained in a text file and formatted as such.
/var/www/xxx/html/videos/video_folder_1
/var/www/xxx/html/videos/video_folder_2
/var/www/xxx/html/videos/video_folder_3
/var/www/xxx/html/videos/video_folder_4
/var/www/xxx/html/videos/video_folder_5
/var/www/xxx/html/videos/video_folder_6
/var/www/xxx/html/videos/video_folder_7
I also have a variable called %file_name% in the batch file already defined.
So lets say that is it is %file_name% = V001-video_folder_6.mp4
As you can see there is some more extra information, V001- and .mp4.
I would like to use the var %file_name% to search the text file and return the entire line. In this case it would return /var/www/xxx/html/videos/video_folder_6 and then put this information in a new var, let us say, %folder_path%.
I think I would use findstr however I have been playing around and not getting the best results.
The problem with the methods that use findstr is that they are slow, because they require to execute findstr.exe (a ~30KB file) each time. A simpler/faster solution is to use just internal Batch commands with the aid of an array. If the number of names to process is large, the difference in time between the two methods may be marked.
#echo off
setlocal EnableDelayedExpansion
rem Load the lines from text file into an array with the last part as index:
for /F "delims=" %%a in (test.txt) do (
set "line=%%a"
for %%b in (!line:/^= !) do set "lastPart=%%b"
set "folder[!lastPart!]=%%a"
)
set "file_name=V001-video_folder_6.mp4"
rem Get the folder from file_name:
for /F "tokens=2 delims=-." %%a in ("%file_name%") do set "folder_path=!folder[%%a]!"
echo Folder path is: %folder_path%
Let us assume the posted lines are in file Test.txt in current working directory.
#echo off
set "file_name=V001-video_folder_6.mp4"
for /F "tokens=2 delims=-." %%A in ("%file_name%") do set "folder=%%A"
for /F "delims=" %%P in ('%SystemRoot%\System32\findstr.exe "/C:%folder%" Test.txt') do (
set "folder_path=%%P"
goto NextCommand
)
:NextCommand
echo Full folder path is: %folder_path%
Open a command prompt window, enter the command for /?, hit key RETURN or ENTER and read output help to understand this little code.
The command goto inside FOR loop results in an immediate exit from loop processing output of findstr.exe after first found line containing the folder path of interest.
Perhaps better in case of searched folder is not found in text file:
#echo off
set "file_name=V01-VIDEOS for school (Miss Patrick).mp4"
for /F "tokens=2 delims=-." %%A in ("%file_name%") do set "folder=%%A"
for /F "delims=" %%P in ('%SystemRoot%\System32\findstr.exe "/C:%folder%" Test.txt') do (
set "folder_path=%%P"
goto FoundFolder
)
echo "%folder%" not found in file Test.txt.
pause
goto :EOF
:FoundFolder
echo Full folder path is: "%folder_path%"
pause
This should work:
::file_name=V001-video_folder_6.mp4
::file containing folder paths is called paths.txt
for /f "tokens=2 delims=-." %%a in ("%file_name%") do set FN=%%a
for /f %%a in ('findstr /E /L "%FN%" "paths.txt"') do set folder_path=%%a
echo %folder_path%
Which does what you want in effectively two lines.
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 :)
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
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
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
)
My requirement is I am Creating a text using dos command to store date using
Echo %date% > Sample.txt
Now I should read the Sample.txt to check for the date value and based on the current date I should call another batch file
This thread ponders your question and has at least one solution:
http://www.computerhope.com/forum/index.php?topic=112106.0
create another file with today's date
compare the files with FC
use FIND to check if FC's output says no differences
Use FIND's returned error level to branch your batch file
FC c:\Download\TodayFile.txt c:\Yesterday\File.txt /L | FIND "FC: no dif" > nul
IF ERRORLEVEL 1 goto different
echo Files are the same.
goto end
:different echo Files are different.
:end
WRITE
#echo off
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
set ldt=%ldt:~0,4%-%ldt:~4,2%-%ldt:~6,2% %ldt:~8,2%:%ldt:~10,2%:%ldt:~12,6%
echo %ldt% > test.txt
READ
#echo off
for /f %%a in (test.txt) do (
echo %%a
pause
)
I have a number of TSV files in a directory, and I would like to append the file name as an extra column on every line.
For Example my data looks like the below.
BEFORE
FileName: snapper_User_list.txt
Username group
user1 admin
user2 users
FileName: marlin_User_list.txt
Username group
root admin
sql admin
My ideal state would to be have one text file that looks like the below.
AFTER
FileName: output.txt
user1 admin snapper
user 2 users snapper
root admin marlin
sql admin marlin
For now I need to complete this in MS Windows.
I have the below script working, although it still displays the full filename in my output.
Rem Rename the files by just using the name before the underscore.
for /f "tokens=1* delims=_" %%i in ( 'dir *.txt /b' ) do (
rename %%i_%%j %%i.txt
)
Rem Combine the files.
FOR %%I IN (*.txt) DO (
FOR /f "tokens=*" %%a IN (%%I) DO (
echo %%a%TAB%%%I>>combined.txt
)
)
It's pretty ugly code.
Thanks.
(updated - update to my code)
I am going to assume you are referring to an underscore that occurs in the file name.
#echo off
setlocal
::The following defines a TAB character that is not preserved on StackOverflow
set "TAB= "
for %%F in (*.txt) do call :processFile "%%F"
exit /b
:processFile
set "name=%~1"
set name=%name:_=&rem %
for /f "usebackq delims=" %%a in (%1) do echo %%a%TAB%%name%>>combined.txt
The magic command is set name=%name:_=&rem %. It works by injecting a REMark command into the statement. Assume the current name is part1_part2.txt. After the search and replace expansion, the full statement becomes set name=part1&rem part2.txt
EDIT - Improved answer
Looking at your edited question, I realize there is a better way. I should have thought of parsing the name using FOR /F :-) You were 90% there!
#echo off
setlocal
::The following defines a TAB character that is not preserved on StackOverflow
set "TAB= "
for %%F in (*.txt) do (
for /f "delims=_" %%I in ("%%F") do (
for /f "usebackq delims=" %%a in ("%%F") do echo %%a%TAB%%%I>>combined.txt
)
)