I'm scripting a big batch file.
It records the date to a log.txt file:
#echo off
echo %date%, %time% >> log.txt
echo Current date/time is %date%, %time%.
#pause
exit
It can record it several times, on several lines. Now what I want to do is that the batch file file shows the last recorded date/time from the log.txt file.
How?
type log.txt
But that will give you the whole file. You could change it to:
echo %date%, %time% >> log.txt
echo %date%, %time% > log_last.txt
...
type log_last.txt
to get only the last one.
hmm.. just found the answer. it's easier then i thought. it just needs a bunch more stuff:
#echo off
if not exist log.txt GOTO :write
echo Date/Time last login:
type log.txt
del log.txt
:write
echo %date%, %time%. >> log.txt
#pause
exit
So it first reads the log.txt file and deletes it. After that it just get a new file (log.txt) with the date & time!
I hope this helps other people!
(the only prob is that the first time it does not work, but then just enter in random value at log.txt.)
(This problem is solved and edited.)
Use the tail.exe from the Windows 2003 Resource Kit
Try this: use Find to iterate through all lines with "Current date/time", and write each line to the same file:
for /f "usebackq delims==" %i in (`find "Current date" log.txt`) do (echo %i > log-time.txt)
type log-time.txt
Set delims= to a character not relevant in the date/time lines. Use %%i in batch files.
Explanation (update):
Find extracts all lines from log.txt containing the search string.
For /f loops through each line the command inside (...) generates.
As echo > log-time.txt (single > !) overwrites log-time.txt every time it's executed, only the last matching line remains in log-time.txt
Here's a version that doesn't fail if log.txt is missing:
#echo off
if not exist log.txt goto firstlogin
echo Date/Time last login:
type log.txt
goto end
:firstlogin
echo No last login found.
:end
echo %date%, %time%. > log.txt
pause
Ok I wonder when's the use but, here are two snipets you could use:
lastlog.cmd
#echo off
for /f "delims=" %%l in (log.txt) do set TimeStamp=%%l
echo %TimeStamp%
Change the "echo.." line, but the last log time is within %TimeStamp%. No temp files used, no clutter and reusable as it is in a variable.
On the other hand, if you need to know this WITHIN your code, and not from another batch, change your logging for:
set TimeStamp=%date%, %time%
echo %TimeStamp% >> log.txt
so that the variable %TimeStamp% is usable later when you need it.
A handy timestamp format:
%date:~3,2%/%date:~0,2%/%date:~6,2%-%time:~0,8%
Just set the time and date to variables if it will be something that will be in a loop then
:top
set T=%time%
set D=%Date%
echo %T%>>log.txt
echo %d%>>log.txt
echo time:%T%
echo date:%D%
pause
goto top
I suggest making it nice and clean by putting:
#echo off
in front of every thing it get rid of the rubbish C:/users/example/...
and putting
cls
after the :top to clear the screen before it add the new date and time to the display
Here is a good date and time code:
#echo off
if %date:~4,2%==01 set month=January
if %date:~4,2%==02 set month=February
if %date:~4,2%==03 set month=March
if %date:~4,2%==04 set month=April
if %date:~4,2%==05 set month=May
if %date:~4,2%==06 set month=June
if %date:~4,2%==07 set month=July
if %date:~4,2%==08 set month=August
if %date:~4,2%==09 set month=September
if %date:~4,2%==10 set month=October
if %date:~4,2%==11 set month=November
if %date:~4,2%==12 set month=December
if %date:~0,3%==Mon set day=Monday
if %date:~0,3%==Tue set day=Tuesday
if %date:~0,3%==Wed set day=Wednesday
if %date:~0,3%==Thu set day=Thursday
if %date:~0,3%==Fri set day=Friday
if %date:~0,3%==Sat set day=Saturday
if %date:~0,3%==Sun set day=Sunday
echo.
echo The Date is %day%, %month% %date:~7,2%, %date:~10,4% the current time is: %time:~0,5%
pause
Outputs: The Date is Sunday, September 27, 2009 the current time is: 3:07
#echo off
set log=%time% %date%
echo %log%
That is a batch for saving the date and time as a temporary variable, and displaying it.
In a hurry, I don't have time to write a script to open a txt, maybe later.
Related
Let's say I'd have a file named "testfile.txt" set on a variable:%File% and I'd like to remove the extension when echoing it . Echo %File:~0,8% would come out as "testfile" but what I want to do is to have it display anything and everything to the left of the ".txt" because I won't always make files which have 8 characters in their name.
Is there a simple solution to this ?
Yep.
for %%I in ("testfile.txt") do echo %%~nI
or
for %%I in ("%file%") do echo %%~nI
Do help for in a cmd console window and see the last two pages for more information on tilde operations.
There is another way to accomplish what you want, using substring substitution similar to your attempts illustrated in your question.
set "file=testfile.txt"
echo %file:.=&rem;%
That substitutes the dot with &rem;. When the variable is evaluated, the batch interpreter treats the newly substituted data as a compound command. And since everything following rem is treated as a remark to be ignored, you're left with only testfile as the output. This will only work if:
you don't include quotation marks in your variable value
your filename only includes the one dot
you don't do it within a parenthetical code block (if statement or for loop) where delayed expansion is required
You can try this:
#echo off
set "file=testfile.txt"
call :removeExtension "%file%"
echo %newFile%
pause
goto :eof
:removeExtension
set "newFile=%~n1"
goto :eof
However, this only works if the file has no path. If it does, you can do this:
#echo off
setlocal EnableDelayedExpansion
set "file=files\testfile.txt"
call :removeExtension "%file%"
echo %newFile%
pause
goto :eof
:removeExtension
set "file=%~1"
set "newFile=!file:%~x1=!"
goto :eof
I need to create a batch file that would show me a string printed after a specific string in some log file.
For example: I have a log file with a line that ends with the string "Calculated number: XX". I want to create a batch file that would go to that log, find this string and print only XX part to the screen (XX is some number that changes every now and then). Any ideas what is the best way to do that?
Help will be much appreciated, thanks in advance!
The format of the string is what comes before and after the part you are interested in - as it can matter how the line is parsed.
This code is robust and will print the number at the end of the string, if it is indeed at the end.
It uses a helper batch file called repl.bat - download from: https://www.dropbox.com/s/qidqwztmetbvklt/repl.bat
Place repl.bat in the same folder as the batch file or in a folder that is on the path.
#echo off
type "file.log" | repl ".*Calculated number: (.*)" "$1" a
#ECHO OFF
SETLOCAL
FOR /f "delims=" %%a IN (q23040271.txt) DO (
ECHO "%%a"|FIND "Calculated number: " >NUL 2>nul
IF NOT ERRORLEVEL 1 SET "line=%%a"&GOTO found
)
ECHO target NOT found&GOTO :eof
:found
ECHO %line:~-2%
GOTO :EOF
I used a file named q23040271.txt containing junk text and sample data for my testing.
This relies heavily on the assumption that the very first occurrence of Calculated number:
will be the required ite, and that it will be at the end of the line - no checking is done that it is actually at the end of the line.
replacing
ECHO "%%a"|FIND "Calculated number: " >NUL 2>nul
with
ECHO "%%a"|FINDSTR /e /R /c:"Calculated number: ..." >NUL 2>nul
would perform that end-of-line check (in theory - I haven't checked it) - note the three consecutive dots.
This will be agonisngly slow if there are millions of lines - unless the target string is very early in the file.
The more information you provide, the better a solution that can be devised.
I know the title sounds crazy. Anyway, here is my scenario:
I need to create about 500 text files for 500 different files. Each text file will contain the information seen in my example below. Is there an easy way to put this into a single batch file without copy and pasting something 500+ times?
Example of what I am trying to do....
echo ^<filename 1^> >> filename1.txt
echo. >> filename1.txt
echo. >> filename1.txt
echo No OCR Found >> filename1.txt
Using random numbers for the files...
#echo off
set loop=0
:loop
set num=%random%
if exist filename%num%.txt (
echo ^<filename %num%^>
echo.
echo.
echo No OCR Found
) > filename%num%.txt else (
goto loop
)
set /a num+=1
if %loop%==500 goto end
goto loop
:end
NOTE:
The maximum amount of files is 32767.
To change the amount of files made, change the number in the last if statement (E.g: To make it create 80 files you would change if %loop%==500 goto end to if %loop%==80 goto end).
Is there any method in Windows through which we can execute a batch script without *.bat extension?
This is an interesting topic to me! I want to do some observations about it.
The important point first: A Batch file is a file with .BAT or .CMD extension. Period. Batch files can achieve, besides the execution of usual DOS commands, certain specific Batch-file facilities, in particular:
Access to Batch file parameters via %1 %2 ... and execution of SHIFT command.
Execution of GOTO command.
Execution of CALL :NAME command (internal subroutine).
Execution of SETLOCAL/ENDLOCAL commands.
Now the funny part: Any file can be redirected as input for CMD.exe so the DOS commands contained in it are executed in a similar way of a Batch file, with some differences. The most important one is that previous Batch-file facilities will NOT work. Another differences are illustrated in the NOT-Batch file below (I called it BATCH.TXT):
#echo off
rem Echo off just suppress echoing of the prompt and each loop of FOR command
rem but it does NOT suppress the listing of these commands!
rem Pause command does NOT pause, because it takes the character that follows it
pause
X
rem This behavior allows to put data for a SET /P command after it
set /P var=Enter data:
This is the data for previous command!
echo Data read: "%var%"
rem Complex FOR/IF commands may be assembled and they execute in the usual way:
for /L %i in (1,1,5) do (
set /P line=
if "!line:~0,6!" equ "SHOW: " echo Line read: !line:~6!
)
NOSHOW: First line read
SHOW: Second line
NOSHOW: This is third line
SHOW: The line number 4
NOSHOW: Final line, number five
rem You may suppress the tracing of the execution redirecting CMD output to NUL
rem In this case, redirect output to STDERR to display messages in the screen
echo This is a message redirected to STDERR >&2
rem GOTO command doesn't work:
goto label
goto :EOF
rem but both EXIT and EXIT /B commands works:
exit /B
:label
echo Never reach this point...
To execute previous file, type: CMD /V:ON < BATCH.TXT
The /V switch is needed to enable delayed expansion.
More specialized differences are related to the fact that commands in the NOT-Batch file are executed in the command-line context, NOT the Batch-file context. Perhaps Dave or jeb could elaborate on this point.
EDIT: Additional observations (batch2.txt):
#echo off
rem You may force SET /P command to read the line from keyboard instead of
rem from following lines by redirecting its input to CON device.
rem You may also use CON device to force commands output to console (screen),
rem this is easier to write and read than >&2
echo Standard input/output operations> CON
echo/> CON
< CON set /P var=Enter value: > CON
echo/> CON
echo The value read is: "%var%"> CON
Execute previous file this way: CMD < BATCH2.TXT > NUL
EDIT: More additional observations (batch3.txt)
#echo off
rem Dynamic access to variables that usually requires DelayedExpansion via "call" trick
rem Read the next four lines; "next" means placed after the FOR command
rem (this may be used to simulate a Unix "here doc")
for /L %i in (1,1,4) do (
set /P line[%i]=
)
Line one of immediate data
This is second line
The third one
And the fourth and last one...
(
echo Show the elements of the array read:
echo/
for /L %i in (1,1,4) do call echo Line %i- %line[%i]%
) > CON
Execute this file in the usual way: CMD < BATCH3.TXT > NUL
Interesting! Isn't it?
EDIT: Now, GOTO and CALL commands may be simulated in the NotBatch.txt file!!! See this post.
Antonio
Just use:
type mybat.txt | cmd
Breaking it down...
type mybat.txt reads mybat.txt as a text file and prints the contents. The | says capture anything getting printed by the command on its left and pass it as an input to the command on its right. Then cmd (as you can probably guess) interprets any input it receives as commands and executes them.
In case you were wondering... you can replace cmd with bash to run on Linux.
in my case, to make windows run files without extension (only for *.cmd, *.exe) observed, i have missed pathext variable (in system varailbles) to include .cmd. Once added i have no more to run file.cmd than simply file.
environment variables --> add/edit system variable to include .cmd;.exe (ofcourse your file should be in path)
It could be possible yes, but probably nor in an easy way =) cause first of all.. security.
I try to do the same thing some year ago, and some month ago, but i found no solution about it.. you could try to do
execu.cmd
type toLaunch.txt >> bin.cmd
call bin.cmd
pause > nul
exit
then in toLaunch.txt put
#echo off
echo Hello!
pause > nul
exit
just as example, it will "compile" the code, then it will execute the "output" file, that is just "parse"
instead of parsed you could also just rename use and maybe put an auto rename inside the script using inside toLaunch.txt
ren %0 %0.txt
hope it helped!
It is possible at some degree. You'll need an admin permissions to run assoc and ftype commands. Also a 'caller' script that will use your code:
Lets say the extension you want is called .scr.
Then execute this script as admin:
#echo off
:: requires Admin permissions
:: allows a files with .scr (in this case ) extension to act like .bat/.cmd files.
:: Will create a 'caller.bat' associated with the extension
:: which will create a temp .bat file on each call (you can consider this as cheating)
:: and will call it.
:: Have on mind that the %0 argument will be lost.
rem :: "installing" a caller.
if not exist "c:\scrCaller.bat" (
echo #echo off
echo copy "%%~nx1" "%%temp%%\%%~nx1.bat" /Y ^>nul
echo "%%temp%%\%%~nx1.bat" %%*
) > c:\scrCaller.bat
rem :: associating file extension
assoc .scr=scrfile
ftype scrfile=c:\scrCaller "%%1" %%*
You even will be able to use GOTO and CALL and the other tricks you know. The only limitation is that the the %0 argument will be lost ,tough it can be hardcoded while creating the temp file.
As a lot of languages compile an .exe file for example I think this a legit approach.
If you want variables to be exported to the calling batch file, you could use
for /F "tokens=*" %%g in (file.txt) do (%%g)
This metod has several limitations (don't use :: for comments), but its perfect for configuration files.
Example:
rem Filename: "foo.conf"
rem
set option1=true
set option2=false
set option3=true
#echo off
for /F "tokens=*" %%g in (foo.conf) do (%%g)
echo %option1%
echo %option2%
echo %option3%
pause
I'm currently creating a batch script that has to loop through the lines in a file, checking for some string, and if theres a match prefix that string with a '#' (comment it out).
I'm perfectly new to batch script, all I got this far is:
for /f %%j in (CMakeLists.txt) do (
if "%%j"=="Extensions_AntTweakBar" (
echo lol1
)
if "%%j"=="Extensions_Inspection" (
echo lol2
)
if "%%j"=="Extensions_InspectionBar" (
echo lol3
)
)
So my current issue is, I don't know how to operate on string within batch scripts. If someone could help me out that would be appreciated :)
You can just use the text you want to append followed by your variable generally.
C:\>set MY_VAR=Hello world!
C:\>echo #%MY_VAR%
#Hello world!
C:\>set MY_VAR=#%MY_VAR%
C:\>echo %MY_VAR%
#Hello world!
If you're just doing echo, that's fine. echo #%%j will do what you need.
But if you want to set the line to a variable, you have to enable delayed expansion. Add setlocal ENABLEDELAYEDEXPANSION to the top of your file and then surround your variables with ! instead of %. For example (and notice that I've added delims= to put the entire line in %%j instead of the first word on the line):
#echo off
setlocal ENABLEDELAYEDEXPANSION
set LINE=
for /f "delims=" %%j in (CMakeLists.txt) do (
set LINE=%%j
if "%%j"=="Extensions AntTweakBar" (
set LINE=#%%j
)
if "%%j"=="Extensions Inspection" (
set LINE=#%%j
)
if "%%j"=="Extensions InspectionBar" (
set LINE=#%%j
)
echo !LINE!
)
Given this input file:
Extensions AntTweakBar
some text
Extensions Inspection
Extensions What?
some more text
Extensions InspectionBar
Extensions InspectionBar this line doesn't match because delims= takes all text
even more text
The above script produces this output:
C:\>comment.bat
#Extensions AntTweakBar
some text
#Extensions Inspection
Extensions What?
some more text
#Extensions InspectionBar
Extensions InspectionBar this line doesn't match because delims= takes all text
even more text
And of course removing #echo off will help you debug problems.
But all that being said, you're about at the limit of what you can accomplish with batch string processing. If you still want to use batch commands, you may need to start writing lines to temporary files and using findstr with a regex.
Without a better understanding of what you want inside your loop or what your CMakeLists.txt file looks like, try this on for starters:
FINDSTR "SOMETHING" %%J && ECHO #%%J || ECHO %%J
The && makes the second command (the ECHO) conditional on the first command exiting without an error state, and the || is like a logical OR and it runs when the first one doesn't.
Really, for modifying the internals of a text file you are probably going to be much better off using either sed or awk - win32 binaries can be found in the UnxUtils project.