"Echo is On" Output to text file blank - batch-file

for /f %%C in ('Find /V /C "" ^< mamegamelist.txt') do set Count=%%C
echo The file has %Count% lines.
echo %Count%>gamecount.txt
set /p texte=< mamegamelist.txt
echo %texte%>currentgame.txt
set/a played=3379-%Count%
echo %played%>played.txt
pause
Everything works fine except for this line:
set/a played=3379-%Count%
echo %played%>played.txt
It evaluates correctly, but it doesn't write out anything to the file.
If I change the arithmetic expression to something like this:
set/a played=%Count%+2
echo %played%>played.txt
It will work perfectly fine. I'm pretty sure I don't have any unnecessary spaces anywhere. Any help appreciated!

You don't tell us what numbers you are using.
If mamegamelist.txt is empty or has fewer than 10 lines, you get an echo is off message from the first redirected echo.
A single digit before a redirector redirects an output stream to the file. Somethimes the syntax can be tricky to formulate.
Try
>played.txt echo %played%
(and follow the bouncing ball for any other possible exactly-1-digit-before-a-redirector instructions, like to gamecount.txt)
By placing the redirector at the start of the line, any problem with the syntax is avoided.

Related

BATCH file reloading autorun buffer

There are things that we prefer not to understand in order to have an easier life to live.
But this is not something I can choose...
I made a batch file (or macro.doskey) to get the charset code. And it worked perfectly for a long time...
Basically it runs chcp:
> chcp
Code page active: 850
and then wraps the return before and after the colon
assigning what comes after to a variable:
FOR /F "tokens=1,* delims=:" %%s in ('CHCP') do (
#ECHO %%t
IF NOT "%1" == "" (SET %1=%%t)
)
For example:
> getCHCP.bat myVar
850
> ECHO %myVar%
850
However it started to lock, waiting for ENTER or displaying several echo messages. For example:
> getchcp myVar
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
850
I started to mix until I decided to change the ECHO %%t to ECHO %%s, and guess what?
No, is that the Bill Gates skull? Is it an easter egg from Microsoft? A virus?
No, none of that, this is just my autorun's welcome message.
This can be configured in
<[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor]autorun>
In my case I called a batch file which, among other things, gives several echos showing this skull on the screen.
But the question is, why does it act like it reloads the autorun in background
when I've already opened the command prompt?
And why does it leave
everything in the buffer so that %%s pulls it again to the (Page code active) ':'?
And why are
you giving lots of ECHO is off on %%t when the only thing after
Code page active: is a number?
And the most important: How I solve it?
It's obvious, you already point to the problem.
this is just my autorun's welcome message.
This can be configured in
<[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor]autorun>
The line FOR /F %%s in ('CHCP') ... start CHCP but that will be done in a NEW child cmd.exe instance.
And a NEW cmd.exe instance runs the autorun command!
Just before it starts your chcp.
You can disable the autorun at all, or add some code to detect the difference between a new cmd.exe instance for the user against a new instance from a FOR /F.
Put this code at the start of your autorun batch file
#echo off
setlocal EnableDelayedExpansion
REM *** ALWAYS make a copy of the complete CMDCMDLINE, else you destroy the originial!!!
set "_ccl_=!cmdcmdline!"
REM *** %1 contains only data, when the script itself was called from the command line
if "%~1" NEQ "" (
goto :direct_call
)
REM *** The check is necessary to distinguish between a new cmd.exe instance for a user or for a "FOR /F" sub-command
if "!_ccl_:~1,-2!" == "!comspec!" (
REM ***** INTERACTIVE ****
REM *** Show your skull or something else
)
exit /b

Why doesn't my text grabber work in batch?

I am developing a program in batch that will play the board game Talisman (second edition). It is in very early development and not ready for testing.
At one point in the code I need to print the top line of a text document. This part of the code looks like this:
find /I "alchemy" priorities.txt >nul
if %errorlevel%==0 (
set /p alchemObj=< 2Alchemise.txt
echo I will visit the alchemist in the city.
echo.
echo The Alchemist converted my %alchemObj% into 1 gold
set /a gold=%gold%+1
echo I now have %gold% gold.
for /f "skip=1 delims=*" %%a in (2Alchemise.txt) do (
echo %%a >>newfile.txt
)
xcopy newfile.txt 2Alchemise.txt /y >nul
del newfile.txt /f /q >nul
)
When this program is run everything except the
echo The Alchemist converted my %alchemObj% into 1 gold
seems to work. When it is run it prints "The Alchemist converted my into 1 gold"
I have tried running:
set /p alchemObj=< 2Alchemise.txt
and then
echo The Alchemist converted my %alchemObj% into 1 gold
and it seems to work just as expected.
Thanks for your help, Edje
(Click here to download whole file)
Thanks a lot to michael_heath for their answer.
I was using delayed expansion for an earlier part of the code. For what ever reason I needed to use the '!' variable deliminator instead of the default '%' deliminator.
Thanks also to Squashman and Mofi as I used these suggestions to improve my code further.
Thanks a lot this have given me a great first impression of Stack Overflow.
Evyn

How do I echo strings on the same line as a previous echo?

How do I echo "I have 1 number" using two echo commands in a batch file?
echo "I have "
...
... do stuff
...
echo "1 number"
creates two lines:
I have
1 number
how do I suppress the cr/lf on the first echo? to create:
I have 1 number
this appears to do it:
<nul set /p=I have
echo 1 number
note that this example is too simplistic- in a more general case the second part is not just an echo but the result of some calculation or manipulation, for example cd:
<nul set /p=set currentdir=>a.bat
cd>>a.bat
I can't see that this functionality is possible with the PART1 answer given above.
Perhaps I am missing part of the problem. Save the first part in a variable, then use it later with the latter part.
SET "PART_1=I have "
.
... do stuff
.
ECHO %PART_1% 1 number
How about...
C:\Users\lit\t>ECHO SET "currentdir=%CD%" >a.bat
C:\Users\lit\t>type a.bat
SET "currentdir=C:\Users\lit\t"
Multiple lines...? The ECHO command writes a newline CRLF at the end of anything it outputs. You are not going to get a subsequent ECHO command to write over the newline from the first ECHO. How about...
SET TMPFILE=%TEMP%\mytempfile.tmp
ECHO>"%TMPFILE%" I have
... do stuff
FOR /F "usebackq tokens=*" %%a IN (`TYPE "%TMPFILE%"`) DO (SET "S1=%%~a")
ECHO %S1% 1 file
IF EXIST "%TMPFILE%" (DEL "%TMPFILE%")

Windows batch - Breaking out of a loop using variables

So, I've been trying to create a simple spinning line thing that goes on for a set number of loops. I've encountered a problem: I can't find a way to add to a variable, or have a loop counter. This is my code so far (Other general criticisms are accepted too: I'm new to this and it all helps.)
#echo off
:1
echo
echo
echo
echo -
echo
cls
echo
echo
echo /
echo
cls
echo
echo
echo I
echo
cls
echo
echo
echo \
echo
cls
echo
echo
echo -
echo
IF %timer%
goto 1
pause
Really sorry if it's already been asked; I just can't seem to find what I'm looking for. Also, it's very possible this could just be a simple command, in which case i apologise again.
There's a couple of errors with your code as it stands.
The major one is
IF %timer%
goto 1
Batch is a ver old-fashioned language and is very particular about syntax. You can get a syntax description by typing
if /? |more
at the prompt. (replace if with the keyword you desire)
if requires
if string1==string2 thingtodoiftrue
Over the years, the syntax has been expanded, still maintaining the old version for compatibility so that the general form is now
if string1==string2 (thingtodoiftrue) else (thingtodoiffalse)
where == may now be a number of operators (equ, neq, ...); you can add a /i switch to make the strings case-insensitive, or a not keyword to reverse the sense. The parentheses are optional if the thingtodo is a single statement.
There are some quirky syntax requirements however. Either thingtodoiftrue or ( must be on the same physical line as the if keyword. The sequence ) else ( must all be on one physical line (if it's used)
As for performing some variety of count using your original structure, there are many ways. Here's one:
#echo off
set count=15
:1
....
set /a count=count-1
IF %count% neq 0 goto 1
pause
This may be what you are looking for. This runs the code 10000 times and it could be modified according to your need.
#echo off
for /l %%i in (1,1,10000) do (
echo -
cls
echo /
cls
echo I
cls
echo \
cls
)
Cheers, G
#echo off
setlocal enableextensions disabledelayedexpansion
rem Get a 0x13 character (carriage return) char inside a variable
for /f %%a in ('copy /Z "%~f0" nul') do set "CR=%%a"
rem Spin the line
setlocal enabledelayedexpansion
for /l %%a in (1 1 5000) do for %%b in (- \ ^| /) do (
set /a "pct=%%a / 50"
<nul set /p ".=%%b !pct!%% !cr!"
)
endlocal
The basic idea is to output the spinning element, followed by the percentage. To keep all the output in the same line
<nul set /p "var=outputtext"
is used. This echoes the indicated text to console, waits for input, that is readed from nul, ending the prompt wait and continues without moving the cursor to the next line. There is no line feed
Now, it is necessary overwrite this line with the new information each time. To do it, it is necessary to get a carriage return character into a variable. For it, the for /f is used, retrieving the needed carriage return character from the output of the copy command.
note: the disabledelayedexpansion is necessary in this step to avoid problems if the full path/filename of the batch file (%~f0) contains any exclamation character.
The remaining code just iterates painting the corresponding character in the list, calculating the percentage to output and printing all to the console, without the line feed (<nul set /p ...) but with an aditional carriage return that moves the cursor to the start of the line. So, the next output will overwrite the previous one
note: in this case, enabledelayedexpansion is needed to get access to the content of the changed percentage variable and to output the carriage return. Without delayed expansion active, the parser removes the carriage return from the output.

CMD.EXE batch script to display last 10 lines from a txt file

Any ideas how to echo or type the last 10 lines of a txt file?
I'm running a server change log script to prompt admins to state what they're doing, so we can track changes. I'm trying to get the script to show the last 10 entries or so to give an idea of what's been happening recently. I've found a script that deals with the last line, as shown below, but can't figure out what to change in it to display the last 10 lines.
Script:
#echo off
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in (c:\log09.txt) do (
set var=%%a
)
echo !var!
Example of log file:
06/02/2009, 12:22,Remote=Workstation-9,Local=,
mdb,bouncing box after updates,CAS-08754,
=================
07/02/2009, 2:38,Remote=,Local=SERVER1,
mdb,just finished ghosting c drive,CAS-08776,
=================
07/02/2009, 3:09,Remote=,Local=SERVER1,
mdb,audit of server,CAS-08776,
Any thoughts?
The script works great, just need it to pipe more lines to the screen.
Hopefully this will save Joel's eyes :)
#echo OFF
:: Get the number of lines in the file
set LINES=0
for /f "delims==" %%I in (data.txt) do (
set /a LINES=LINES+1
)
:: Print the last 10 lines (suggestion to use more courtsey of dmityugov)
set /a LINES=LINES-10
more +%LINES% < data.txt
This answer combines the best features of already existing answers, and adds a few twists.
The solution is a simple batch implementation of the tail command.
The first argument is the file name (possibly with path information - be sure to enclose in quotes if any portion of path contains spaces or other problematic characters).
The second argument is the number of lines to print.
Finally any of the standard MORE options can be appended: /E /C /P /S /Tn. (See MORE /? for more information).
Additionally the /N (no pause) option can be specified to cause the output to be printed continuosly without pausing.
The solution first uses FIND to quickly count the number of lines. The file is passed in via redirected input instead of using a filename argument in order to eliminate the printout of the filename in the FIND output.
The number of lines to skip is computed with SET /A, but then it resets the number to 0 if it is less than 0.
Finally uses MORE to print out the desired lines after skipping the unwanted lines. MORE will pause after each screen's worth of lines unless the output is redirected to a file or piped to another command. The /N option avoids the pauses by piping the MORE output to FINDSTR with a regex that matches all lines. It is important to use FINDSTR instead of FIND because FIND can truncate long lines.
:: tail.bat File Num [/N|/E|/C|/P|/S|/Tn]...
::
:: Prints the last Num lines of text file File.
::
:: The output will pause after filling the screen unless the /N option
:: is specified
::
:: The standard MORE options /E /C /P /S /Tn can be specified.
:: See MORE /? for more information
::
#echo OFF
setlocal
set file=%1
set "cnt=%~2"
shift /1
shift /1
set "options="
set "noPause="
:parseOptions
if "%~1" neq "" (
if /i "%~1" equ "/N" (set noPause=^| findstr "^") else set options=%options% %~1
shift /1
goto :parseOptions
)
for /f %%N in ('find /c /v "" ^<%file%') do set skip=%%N
set /a "skip-=%cnt%"
if %skip% lss 0 set skip=0
more +%skip% %options% %file% %noPause%
You should probably just find a good implementation of tail. But if you really really insist on using CMD batch files and want to run on any NT machine unmolested, this will work:
#echo off
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in (c:\tmp\foo.txt) do (
set var9=!var8!
set var8=!var7!
set var7=!var6!
set var6=!var5!
set var5=!var4!
set var4=!var3!
set var3=!var2!
set var2=!var1!
set var1=!var!
set var=%%a
)
echo !var9!
echo !var8!
echo !var7!
echo !var6!
echo !var5!
echo !var4!
echo !var3!
echo !var2!
echo !var1!
echo !var!
There are several windows implementations of the tail command. It should be exactly what you want.
This one sounds particularly good:
http://malektips.com/xp_dos_0001.html
They range from real-time monitoring to the last x lines of the file.
Edit: I noticed that the included link is to a package It should work, but here are some more versions:
http://www.lostinthebox.com/viewtopic.php?f=5&t=3801
http://sourceforge.net/projects/tailforwin32
If file is too large it can take too long to get count of lines
another way is to use find and pass it a nowhere string
$find /v /c "%%$%!" yourtextfile.txt
this would result an output like this
$---------- yourtextfile.txt: 140
then you can parse output using for like this
$for /f "tokens=3" %i in ('find /v /c "%%$%!" tt.txt') do set countoflines=%i
then you can substract ten lines from the total lines
After trying all of the answers I found on this page none of them worked on my file with 15539 lines.
However I found the answer here to work great. Copied into this post for convenience.
#echo off
for /f %%i in ('find /v /c "" ^< C:\path\to\textfile.txt') do set /a lines=%%i
set /a startLine=%lines% - 10
more /e +%startLine% C:\path\to\textfile.txt
This code will print the last 10 lines in the "C:\path\to\textfile.txt" file.
Credit goes to OP #Peter Mortensen
using a single powershell command:
powershell -nologo "& "Get-Content -Path c:\logFile.log -Tail 10"
applies to powershell 3.0 and newer
I agree with "You should use TAIL" answer. But it does not come by default on Windows. I suggest you download the "Windows 2003 Resource Kit" It works on XP/W2003 and more.
If you don't want to install on your server, you can install the resource kit on another machine and copy only TAIL.EXE to your server. Usage is sooooo much easier.
C:\> TAIL -10 myfile.txt
Here's a utility written in pure batch that can show a lines of file within a given range.To show the last lines use (here the script is named tailhead.bat):
call tailhead.bat -file "file.txt" -begin -10
Any ideas how to echo or type the last
10 lines of a txt file?
The following 3-liner script will list the last n lines from input file. n and file name/path are passed as input arguments.
# Script last.txt
var str file, content ; var int n, count
cat $file > $content ; set count = { len -e $content } - $n
stex -e ("["+makestr(int($count))) $content
The script is in biterscripting. To use, download biterscripting from http://www.biterscripting.com , save this script as C:\Scripts\last.txt, start biterscripting, enter the following command.
script last.txt file("c:\log09.txt") n(10)
The above will list last 10 lines from file c:\log09.txt. To list last 20 lines from the same file, use the following command.
script last.txt file("c:\log09.txt") n(20)
To list last 30 lines from a different file C:\folder1\somefile.log, use the following command.
script last.txt file("C:\folder1\somefile.log") n(30)
I wrote the script in a fairly generic way, so it can be used in various ways. Feel free to translate into another scripting/batch language.

Resources