batch - Reading lines/var from config file without for command - batch-file

Can you read lines from a config/txt file without the for /f or any for?
Anyways, I wanted to have a config file what determines the color of the prompt.
I have the following batch code:
#echo OFF
color %color%
#echo
cmd
and this .config file:
---------type color here----------
a
Expected output:
color a
And,
set /p color<main.config
Only reads the first line of the file.

It's so easy with a for:
for /f "eol=-" %%a in (1.config) do color %%a
assuming your config file is like:
---------type color here----------
a
I'd recommend to change your config file a bit (so more than one value can be stored):
---------type color here----------
foreground=e
background=1
and read it with:
for /f "eol=- delims=" %%a in (1.config) do set "%%a"
color %background%%foreground%
Learn more about for /f. It's the most powerful command in batch and worth every minute you spend learning it.

assuming you have your files 1.bat (your batch) and 1.config (configfile)
you can do this if you really dont want to use the for command.
#echo OFF
findstr /V "#" 1.config >1.tmpcfg
set /p COL= < 1.tmpcfg
del 1.tmpcfg
color %COL%
cmd
But I'd prefer using 'for'...
:-)

Related

How to populate undetermined number of variables from text file?

So I know how to save strings to a text file as a list from batch by using
set /p Myvar1="Enter your variable name/value: "
set /p Myvar2="Enter your variable name/value: "
set /p Myvar3="Enter your variable name/value: "
And then append to a text file
echo %Myvar1% %Myvar2% %Myvar3% >> Mylist.txt
So when I open the text file through the batch file, it can be displayed
as a list:
SET "variables="
ECHO =================================================
ECHO My list of stuff
ECHO =================================================
< Mylist.txt (
set /p MyVar1=
set /p MyVar2=
set /p MyVar3=
)
::set line
ECHO - [0] - %Myvar1%
ECHO - [1] - %Myvar1%
ECHO - [2] - %Myvar1%
Now the problem is that:
For each new line on the Mylist.txt text file I have to manually add lines on the batch file. On the provided example the batch is setup so it displays 3 lines of text from the text file. If the text file has 10 lines, it will only show the first 3 lines because that is what is specified. So I would like to accomplish the opposite of this script.
The batch file should be able to:
Batch file reads Mylist.txt.
For each line in Mylist.txt file the batch file creates a "numerated variable".
Each "numerated variable" can be addressable so the user can be prompted to select one of the options on the list 1, 2, 3, 4, etc.
The easiest method to save variable names and their values to a file is redirecting the output of command SET to a file.
set My >"%APPDATA%\MyVariables.txt"
This simple line saves all environment variables starting with My in name with name and value into file MyVariables.txt in application data directory of current user.
And following command line can be used in a batch file to reload those environment variables from file:
for /F "usebackq delims=" %%I in ("%APPDATA%\MyVariables.txt") do set "%%I"
Same command line for usage directly in a command prompt window:
for /F "usebackq delims=" %I in ("%APPDATA%\MyVariables.txt") do set "%I"
A little bit more secure would be checking if each line in the file MyVariables.txt really starts with My as expected and so was not manipulated by someone who wants to override for example PATH by adding manually to file MyVariables.txt a line starting with PATH=.
It might be useful to know how many variables were loaded from file. This can be achieved with a simple extension:
set "VariablesCount=0"
for /F "usebackq delims=" %%I in ("%APPDATA%\MyVariables.txt") do set "%%I" & set /A VariablesCount+=1
Of course if there is an environment variable MyVariablesCount starting with My then this variable with its value would be also saved into the file and reloaded from file which would make it unnecessary to count the number of variables set from file.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
for /?
set /?
Read also the Microsoft article about Using Command Redirection Operators.
simple thing with a for loop plus a counter:
setlocal enabledelayedexpansion
set i=0
for /f "delims=" %%a in (mylist.txt) do (
set /a i+=1
set var[!i!]=%%a
)
echo number of variables: %i%:
set var[
echo ---------
for /l %%a in (1,1,%i%) do echo variable %%a = %var[%%a]%

Batch File - Get filename from directory and save as variable

I am trying to read in a directory and get the filename from that directory.
I then want to save the filename as a variable and echo that filename out.
Here is the code I am using:
for /F %%a in ('dir C:\Users\username\Documents\Training\Pentaho\Outputs\BatchFileOutput\ *.csv') do set FileName=%%a
echo %FileName%
I am getting the following when command prompt runs:
"File not found
Directory"
Does anyone know how to resolve this or where I'm going wrong?
Thanks
Safer way of doing the same:
#echo off
setlocal
set "yourDir=C:\Users\username\Documents\Training\Pentaho\Outputs\BatchFileOutput\"
set "yourExt=*.csv"
pushd %yourDir%
for %%a in (%yourExt%) do echo %%a
popd
endlocal
Sets both: Your directory and the extension you are searching for, Changes the directory to the one previously setted possibly including a /drive change and then runs a loop over all files matching your extension and echo them out. To save only the last one you can use:
...do set fileName=%%a
echo %FileName%
Or to use them all within the loop you can use:
#echo off
Setlocal EnableDelayedExpansion
REM Other things done here
do (
REM Do stuff with %%a here
Set filename=%%a
echo !filename!
echo !filename:~0,6!
echo !filename:a=b!
)
If you just want to echo them, you can just go for echo %%a. If you want to do other things like string-substitution or substrings as described in the comments you need DelayedExpansion as shown above. There are a lot of questions on SO as well.
Note that you can get different "parts" of the path of your file. Have a look on this answer I always have a look on as well. Alternatively check the documentation for the for command typing for /? into the command-line.

How to get just the first line of a text file written into a new text file using a batch file?

Okay I have several lines in a text file. I want to get the first line and save it in another file. For example this is the text file:
put returns between paragraphs
for linebreak add 2 spaces at end
for linebreak add 2 spaces at end2
for linebreak add 2 spaces at end3
I want put returns between paragraphs to be saved into another file.
I used
for /f "tokens=" %%A in ('findstr /r "^[0-9][0-9]*$" <"C:\Users\Sherlock\Desktop\AbcImport\123.txt"') do echo 123>>1234.txt
pause
But it doesn't work at all.
How to get just the first line of a text file written into a new text file using a batch file?
Option 1 - SET /P : This is the simplest and fastest pure batch solution, provided the line does not exceed 1021 bytes, and it does not end with control characters that must be preserved. The size of the file does not matter - it will always read and write the first line very quickly.
#echo off
setlocal enableDelayedExpansion
set "ln="
<"input.txt" set /p "ln="
>"output.txt" (echo(!ln!)
Option 2 - FOR /F : This will work with lines up to ~8191 bytes long, but it can be slow if the file is really large because the FOR /F loop must read the entire file before it processes the first line. This solution is basically the same as the Mofi answer, except it disables the EOL option, so it never ignores the first line, regardless what the first character is. It does have a limitation that it will skip empty lines, so technically it does not give the correct result if the first line is empty:
#echo off
for /f usebackq^ delims^=^ eol^= %%A in ("input.txt") do echo(%%A>"output.txt"&goto :break
:break
There is a way to preserve the first line if it is empty using pure batch, but I would not bother. I would move on to ...
Option 3 - JREPL.BAT, or some other non-batch solution : Batch is quite poor at manipulating text files. You are much better off using some other scripting language like VBScript, JScript, or Powershell. Or a Windows port of any number of unix utilities.
I would use JREPL.BAT - a hybrid JScrpit/batch regular expression text processing utility that runs natively on any Windows machine from XP onward. It is way overkill for such a simple task, but it is an extremely handy, powerful, and efficient tool to have in your arsenal. Once you have it, then it can be used for many text processing tasks. Full documentation is embedded within the script.
jrepl "^.*" "$&" /jendln "quit=true" /f "input.txt" /o "output.txt"
Use CALL JREPL if you put the command within a batch script.
Here is the batch code to write just first non blank/empty line of a text file into another text file.
#echo off
for /F "usebackq delims=" %%I in ("InputTextFile.txt") do (
echo %%I>"OutputTextFile.txt"
goto ContinueAfterLoop
)
:ContinueAfterLoop
InputTextFile.txt is the file in current directory containing the first line to copy.
OutputTextFile.txt is the file created in current directory with first line from input file copied into this output file.
The command GOTO is used to exit the loop after first line is processed and continue the batch file below the loop.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
for /?
goto /?
Read also the Microsoft article about Using Command Redirection Operators.
You can use use this command:
SetLocal EnableDelayedExpansion
for /f "tokens=* delims=;" %%m in ("C:\Users\Sherlock\Desktop\AbcImport\123.txt") do (
set /p FirstLine=<%%m
echo !FirstLine!>>1234.txt
)
and for multiple file:
SetLocal EnableDelayedExpansion
for %%a in ("*") do (
for /f "tokens=* delims=;" %%m in ("%%a") do (
set /p FirstLine=<%%m
echo !FirstLine!>>1234.txt
)
)
rem Get the first line of a text file:
set /P "line=" < "C:\Users\Sherlock\Desktop\AbcImport\123.txt"
rem Write it into a new text file:
echo %line%> 1234.txt

Save specific line from text via batch

So I'm trying to save the contents from the second line of a text file as a variable using Batch. I know there are way better scripting languages to do this with, but batch has command line simplicity that I need. I found this webpage: http://www.netikka.net/tsneti/info/tscmd023.htm But it seems that this method requires an auxiliary program called SED be installed. Are there any methods that do not require SED?
A for loop could work ..
#echo off
Setlocal enabledelayedexpansion
For /f "skip=1 tokens=*" %%a in (myfile.txt) do (
Set secondline=%%a
goto finish
)
: finish
Echo this is my variable !secondline!
Pause

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