for kindness I have a myTextFile.txt that contain something like this:
"C0001.MXF"
"C0002.MXF"
"C0003.MXF"
...
"C0020.MXF"
I would like do a batch that echo only the last item, in this case C0020.mxf
Possibly I need to put the result in 2 variables:
one called var1 = "C0020.MXF"
and another call var2 = C0020.MXF (the same of var1 without the "")
How can I do? thanks
for /f %%a in (mytextfile.txt) do set var=%%~a
echo %var%
derived from any of hundreds of similar solutions.
Since you claim this doesn't work, then the only conclusion I can draw is that the file is a single line, not a series of lines as proposed.
for /f "delims=" %%a in (mytextfile.txt) do for %%b in (%%a) do set var=%%~b
echo %var%
Related
I am trying to write this Batch script to extract the two parameters from an XML file that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<!--<var name="SqlConnection" value="data source=SERVERNAME;initialcatalog=DB_NAME;user id=JackDaniels;password=G235X" />-->
<var name="SqlConnection" value="data source=SERVERNAME;initial catalog=DB_Name;Integrated Security=SSPI" />
My objective is to extract SERVERNAME and DB_NAME from the line that is not commented out.
So far my code looks like this:
#echo off
setlocal enableextensions disabledelayedexpansion
set "connectionString="
set result=""
set "INPUT_FILE=DBConnection.config"
FOR /F "tokens=* delims=<var eol=!" %%x in (%INPUT_FILE%) DO (
ECHO %%x
)
PAUSE
I'm just not sure how to get everything right after "data source=" and "initial catalog=". Is there an easy way to do this?
The adequate way to extract this data is not via a Batch file, but with the methods suggested in a comment. However, the Batch file below perform this extraction in a relatively simple way:
#echo off
setlocal EnableDelayedExpansion
rem From the line that have "<var" followed by "value"...
for /F "delims=" %%a in ('findstr "\<var.*value" input.txt') do (
rem ... process the parts separated by space or equal sign, excepting if enclosed in quotes...
for %%b in (%%a) do (
rem ... and store the part after "value" variable
if "!var!" equ "value" set "value=%%~b"
set "var=%%~b"
)
)
rem Separate "value" string at semicolons and assign each part via SET command
for %%a in ("%value:;=" "%") do set %%a
rem Show results:
echo data source=%data source%
echo initial catalog=%initial catalog%
echo Integrated Security=%Integrated Security%
Output example:
data source=SERVERNAME
initial catalog=DB_Name
Integrated Security=SSPI
Of course, if the data format described in the code changes, the program will fail...
#ECHO Off
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q42420941.txt"
FOR %%v IN (initial catalog data source initial_catalog data_source) DO SET "%%v="
FOR /f "delims=<>" %%z IN ('findstr /B /L /C:"\<var name" "%filename1%"') DO (
FOR %%y IN (%%z) DO (
FOR %%a IN (%%~y) DO (
SET "alive=Y"
FOR %%m IN (initial catalog data source) DO IF /i "%%a"=="%%m" SET "alive="&set %%a=Y
IF DEFINED alive (
IF DEFINED initial IF DEFINED catalog SET "initial_catalog=%%a"
IF DEFINED data IF DEFINED source SET "data_source=%%a"
)
IF DEFINED catalog IF NOT DEFINED initial SET alive=y
IF DEFINED source IF NOT DEFINED data SET alive=y
IF DEFINED alive FOR %%v IN (initial catalog data source) DO set "%%v="
)
)
)
ECHO %initial_catalog% and %data_source%
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
I used a file named q42420941.txt containing your data for my testing.
first, clear out the variable-names.
next, parse each line that passes the findstr which is looking for lines that /L literally /B begin with the /c: character-sequence "< escaped by \) and take the first token delimited by > or <.
This neatly strips the awkward <> from the string and assigns the contents of the selected line to %%z
Next, use a simple for to present each token in the line to %%y.
Then with the quotes stripped off of %%y assign each token to %%a.
Search for a match against the keywords, and set the variable of the same name if found. Clear alive if a keyword is found.
If the string in %%a is not one of the keywords, then check to see whether initial and catalog are both set. If so, this is the required string, so assign it.
if catalog is found but not initial then mark as alive
If alive is still set, then we can clear the flags and wait for the start of another sequence.
OK - it has its faults. It won't detect initial_catalog/data_source if either is one of the four keywords (unlikely) and it assumes that the wanted data is the token following the two keywords - the = becomes a separator in the for list.
Since many of you suggested that Batch is not an adequate way of doing this, I decided to play around with PowerShell, and was able to accomplish what I wanted with just a few lines, and some Regex!
$configPath = $PSScriptRoot + "DBConnection.config"
[xml]$XmlDocument = Get-Content -Path $configPath
$dataSource = $XmlDocument.var.Attributes[1].Value.ToString() # Extract the uncommented line, and the second attribute "value"
$serverName = ($dataSource -split 'data source=([^;]*);')[1]
$db_name = ($dataSource -split 'initial catalog=([^;]*);')[1]
$user_id = ($dataSource -split 'id=([^;]*);')[1]
$user_pass = ($dataSource -split 'password=([^;]*)')[1]
I have a problem taking a text file with 2 lines of text inside of it, and converting each line of the file into a separate variable.
I thought I could just repeat the same process for getting one line of text and just add skip=1 next to delims= and change the name of the variable it goes into, this did not work how I planned and I can't figure out another way to do it.
Here is my code:
#echo off
for /f "delims=" %%a in (file.txt) do (
set line1=%%a
)
for /f "skip=1 delims=" %%a in (file.txt) do (
set line2=%%a
)
echo %line1%
echo %line2%
pause
The text inside the file file.txt is this:
This is the Text on line 1
This is the Text on line 2
Instead of what i thought the output was going to be -
This is the Text on line 1
This is the Text on line 2
Press any key to continue...
It was this:
This is the Text on line 2
This is the Text on line 2
Press any key to continue...
It just prints the second line of the text file for both of the echos!
Please respond to this question as me not knowing how to do this is really bugging me
Thanks, Alex
This is a simple way:
#echo off
< file.txt ( set /P "line1=" & set /P "line2=" )
echo %line1%
echo %line2%
If you want to read more lines, or a variable number of lines, I suggest you to read Arrays, linked lists and other data structures in cmd.exe (batch) script
Take a look at this:
vars.txt (file with variables):
var1
var2
var3
tast.bat:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET varFile=vars.txt
SET i=1
FOR /F %%l IN (%varFile%) DO (
SET line!i!=%%l
SET /a i=!i!+1
)
ECHO !line1!
ECHO !line3!
PAUSE
Output:
var1
var3
This will work regardless how many lines/variables you have. If you have only one, it will be stored in !line1!, if you have 1000, the 500th line will be stored in !line500! and so on.
This should work for lines with spaces by the help of tokens=*
#echo off
rem Creating env testing
(echo First blank line should be skiped
for /l %%i in (1,1,30) do ( echo This is the Text on line %%i)
)>_vars.tmp
setlocal enabledelayedexpansion
set i=1
for /F "skip=1 tokens=*" %%a in (_vars.tmp) do (
set line!i!=%%a
set /a i+=1
)
echo:!line1!
echo:!line3!
echo:!line30!
echo:!line100!
echo checking _vars.tmp
more _vars.tmp
del _vars.tmp
pause
exit /b 0
I am getting only 1 item: Adding - RegistrationPool for the following for loop below. What have I done wrong? How do I iterate to the next token/item?
for /F "delims=!" %%i in ("RegistrationPool"!"SubSystemService") DO (
echo Adding - %%i
echo.
)
if you use a comma or a space instead of an exclamation mark, you can simply use:
for %%i in (RegistrationPool,SubSystemService) DO (
echo testing %%i
echo.
)
To split a string you need a string to split
for /F "delims=!" %%i in ("RegistrationPool!SubSystemService") DO (
echo Adding - %%i
)
But this will still only print one "Adding" line. Why?. for /f will iterate over the files/lines, executing the content of the do body once per line. You have only one line (with two tokens, but one line) so only one iteration.
You can access the second element as a second token
for /F "tokens=1,2 delims=!" %%i in ("RegistrationPool!SubSystemService") DO (
echo Adding - %%i
echo Adding - %%j
)
First token is stored in the indicated replaceable parameter, and the following tokens in alphabetical order.
But, if iterating over a list is what is needed, then the correct construct is
for %%i in ("RegistrationPool" "SubSystemService") DO (
echo Adding - %%i
)
Now, there is a for command iterating over a list of elements. Two elements, two iterations, two "Adding" lines.
I have this format on a .txt file:
"Rosina Merola (rosina_merola#hotmail.com)" <rosina_merola#hotmail.com>
"Sabina Morales (sabinamorales#gmail.com)" <sabinamorales#gmail.com>
"Sorella Blanco (zoreblanco#hotmail.com)" <zoreblanco#hotmail.com>
"Eduardo Schmilinsky Leal" <ejsl41#hotmail.com>
"Elba RodrÃguez" <elbameister#gmail.com>
Ernesto Ramirez <ernestoramirezricca#hotmail.com>
Some of the names have ""and a few don't, as you can see in this example.
However, i need to add a comma ',' after each name and before the email line <>
I thought that first adding the "" to every name, it could be easier then to add the commas, i have this code:
#echo off
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in (nombresemails.txt) do (
echo "%%a", >> nombresemailscomillas.txt
)
It works but it adds the "" in this format:
"Adam Podlinski <apodlinski#cantv.net> ",
"Adam Podlinski 2 <apodlinski#yahoo.com>",
""Aldo Gonzalez " <aldodanielg#hotmail.com>",
""Alejandr Rubin" <rubin4#cantv.net>",
""Alfredo Huguett " <alfredohuguettc#hotmail.com>",
""aainiguezf#gmail.com" <aainiguezf#gmail.com>",
No matter what are the characters it just adds the "" even if they already have it, and besides, it adds them to all the line, i just need to add them to every name, leaving the emails inside the <> without the "".
Anyway, this is just an approach i thought it could work, basically i just need to add a comma after every name and before the emails cointained in <>
there is actually some way achieve this on batch code?
Thanks in advance!
This works here:
#echo off
setLocal EnableDelayedExpansion
for /f "delims=" %%a in (nombresemails.txt) do (
set "line=%%a"
set "line=!line: <=,<!"
>>nombresemailscomillas.txt echo !line!
)
As the title says, I'm trying to pick up to four random files (wallpapers) from a folder, for further processing. The folder does not contain subfolders, just *.jpg's, *.bmp's and *.png's (it may contain a Thumbs.db file, but I already took care of that).
I read all the files with a for loop making something similar to an array, then I'd like to run another for loop for making the random numbers that will act as indexes for choosing the files.
setlocal enabledelayedexpansion
set "wps=1 2 3 4"
set /a ind = 0
for /f "tokens=* delims=" %%g in ('dir C:\Wallpapers /a:-h-s /b /s') do (
set /a ind += 1
set "!ind!=%%g"
)
for %%g in (%wps%) do (
set /a "num = (((!random! & 1) * 1073741824) + (!random! * 32768) + !random!) %% %ind% + 1"
echo Wallpaper %%g is #!num! - Title: "!!num!!"
)
Of course the line that echoes just outputs Wallpaper 1 is #118 - Title: "118" instead of Wallpaper 1 is #118 - Title: "C:\Wallpapers\Miami Skyline.jpg".
So my specific question is: how can I double expand a variable inside a for loop?
[Note #1: the line that creates the random number needs to be so long because it gives a good random distribution of values]
[Note #2: I need wps to be stored that way, because sometimes I could need just three wallpapers, not necessarily in numerical order]
Transfer the !num! value to a FOR variable :-)
for %%N in (!num!) do echo Wallpaper %%g is #%%N - Title: "!%%N!"
A few additional pointers:
As written, your DIR command is including folders. You need to add the /A-D option
dir C:\Wallpapers /a:-h-s-d /b /s
Your numeric variable names work in your existing code. But you will have fits if you ever try to access them using normal expansion because %1% will expand as the 1st batch argument instead of the environment variable. In general practice you should avoid beginning an environment variable with a number. You could use:
set wp!ind!=%%g
...
echo Wallpaper %%g is #!num! - Title: "!wp%%N!
You can make your array 0 based by incrementing your counter at the bottom of the loop instead of the top. Then you don't need to add one to your random number. (This tip is trivial. More a matter of style.)
You don't need both "tokens=*" and "delims=". I recommend the latter. "delims=" will keep the entire string. tokens=* will keep the entire string after it strips leading spaces and tabs. A file name can begin with spaces.
Your code will fail if any of the file names contain ! characters. The exclamation will be corrupted during expansion of %%g because of delayed expansion. It is fairly easy to fix by toggling delayed expansion on and of and using a FOR variable to transfer the value across the ENDLOCAL barrier.
Here is the code with all of the recommendations in place
#echo off
setlocal disableDelayedExpansion
set "wps=1 2 3 4"
set /a ind = 0
for /f "tokens=* delims=" %%g in ('dir C:\Wallpapers /a:-h-s-d /b /s') do (
setlocal enableDelayedExpansion
for %%N in (!ind!) do (
endlocal
set "wp%%N=%%g"
)
set /a ind += 1
)
setlocal enableDelayedExpansion
for %%g in (%wps%) do (
set /a "num = (((!random! & 1) * 1073741824) + (!random! * 32768) + !random!) %% %ind%"
for %%N in (!num!) do echo Wallpaper %%g is #%%N - Title: "!wp%%N!"
)
You could use another FOR like dbenham suggested or you could use CALL
call echo Wallpaper %%g is #!num! - Title: "%%!num!%%"
A CALL expands a line a second time, but only the percent expansion, neither delayed nor FOR-loop expansion works in the second reparse of the line.
EDIT: This only works, if the content of num doesn't begin with a number.
But you could use cmd /c to expand a second time, then it works also with numeric names.
cmd /c echo Wallpaper %%g is #!num! - Title: "%%!num!%%"