I am reading a text file (input.txt) line by line.
(For this, I am using for-loop)
Inside for loop, I am storing each line in a variable.
After storing line in a variable, I want to trim N characters from last from the variable and need to use it for my own purpose.
But I am not able to trim last N(N=4) characters :-(.
Example:
input.txt looks like this:
c:\aaa\bbb\ccc\...
c:\111\222\333\...
Script:
#echo off
setlocal enabledelayedexpansion
set Counter=1
for /f %%x in (Input.txt) do (
set "Line_!Counter!=%%x"
set /a Counter+=1
)
set /a NumLines=Counter - 1
for /l %%x in (1,1,%NumLines%) do (
set trimLast4Char=!Line_%%x!
echo %trimLast4Char:~0,-4%
)
Output I am getting:
~0,-4
~0,-4
Output I want:
c:\aaa\bbb\ccc
c:\111\222\333
Related
I want to run a command (in this example echo) for each line of a variable (in cmd, i.e. batch). In this case, the lines are supposed to be separated by \n, but others delimiters should work as well.
Therefore I set a variable:
> set var="foo\nbar"
I then want to run my command (echo) on each line, i.e. on "foo" and "bar". I tried to use for for this:
> for /f "tokens=* delims=\n" %s in (%var%) do (echo %s)
foo\nbar
Obviously this isn't what I wanted - I expected something like
foo
bar
How do I achieve this?
You can use a real line feed character to get your desired effect.
setlocal EnableDelayedExpansion
(set \n=^
%=empty, do not modify this line=%
)
set "var=foo!\n!bar"
for /f "delims=" %%L in ("!var!") do (
echo ## %%L
)
Other delimiters in the variable
can be used, but have to be replaced later with a linefeed.
setlocal EnableDelayedExpansion
(set \n=^
%=empty, do not modify this line=%
)
set "var=my,list,delimited,by,commas"
for %%L in ("!\n!") do (
for /f "delims=" %%k in ("!var:,=%%~L!") do (
echo ## %%k
)
)
About the delims option in FOR /F
The delims option is for splitting a line into tokens, that will not create more loop iterations - NEVER.
FOR /F "tokens=1,2,3 delims=;" %%A in ("123;456;789") do echo ... %%A, %%B, %%C
Output
... 123, 456, 789
not
... 123
... 456
... 789
%var% is used as the input set to FOR-parcer.
But before running FOR command we should replace \n with space (+outer quotes):
Syntax: %variable:StrToFind=NewStr%
Theese spaces become delimiters in our FOR-parser.
To remove quotes automatically from a a single letter variable use symbol ~
Syntax: %~1
So we have next code:
set var="foo\nbar"
for %%A IN (%var:\n=" "%) DO #ECHO=%%~A
P.S. As jeb truly said the code won't work correctly with special symbols: *, ?, %% in variable content.
I need to get only the every 3rd line of a text file(Movie.txt) and put it on a separate text file(Title.txt) using batch script(for /f)
Movie.txt
Movie
Title
Anime1
Movie
Title
Anime2
Movie
Title
Anime3
Movie
Title
Anime4
Title.txt
Anime1
Anime2
Anime3
Anime4
currently I have no idea how to get the required data...
I would appreciate any help you can provide. thank you.
#echo off
setlocal enabledelayedexpansion
set input=yourinput.txt
set output=youroutput.txt
set i=0
for /f "tokens=*" %%l in (%input%) do (
set /a i=!i!+1
set /a r=!i!%%3
if !r!==0 echo %%l>>%output%
)
We can use the modulo operator and a line counter. !i! contains the line number and !r! is the line number modulo 3. So if !r!==0 we write the line (%%l) into the output file.
#ECHO OFF
SETLOCAL
SET "line1="
SET "line2="
FOR /f "tokens=1*delims=" %%a IN (
'findstr /r "." "100lines.txt"'
) DO (
IF DEFINED line1 (
IF DEFINED line2 (
ECHO %%a
SET "line1="
SET "line2="
) ELSE SET line2=y
) ELSE SET line1=y
)
GOTO :EOF
All you need is to replace the input filename - I have a file named 100lines.txt that contains 100 different lines of text.
Since a variable's current defined status acts on the run-time value of the variable, ensure that the two flags are clear to start, then for each line of the file,
if line1 is not defined, set it
otherwise, if line2 is not defined, set it
otherwise we are on a *3 line, so regurgitate it and clear the two flags.
I want create a batch file to find the total number of commas in the first line of text file.
Sample Text File
input.txt
12345,Bhavik
12323,Bhavik,Sanghvi
Output
1
I tried to surf net for this but couldnt find a solution, please help
Here's another simple solution to this question.
#echo off
setlocal enabledelayedexpansion
set LF=^
::Above 2 blank lines are critical - do not remove
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
set /p var=<input.txt
echo "%var:,="!cr!!lf!"..***..%">temp.file
find /c "..***.." <temp.file
del temp.file
#echo off
setlocal EnableDelayedExpansion
rem Read the first line
set /P "line=" < input.txt
rem Store it in a text file
> before.txt echo !line!
rem Store the line without commas in a second file
> after.txt echo !line:,=!
rem Get the difference in sizes between both files
set "diff="
for %%a in (before.txt after.txt) do (
if not defined diff (
set "diff=%%~Za"
) else (
set /A "diff-=%%~Za"
)
)
del before.txt after.txt
echo %diff%
If, rather than being hampered by the awful Windows BATCH tools, you install awk from the Unix tools for Windows here, you can do this:
awk -F, 'NR==1{print NF-1;exit}' input.txt
That says... "Run awk and use commas as the separator to divide fields. On line 1, print the number of fields on this line minus 1, then exit. Do that for file input.txt."
gawk is just a slightly different version of awk if you get that one in the Unix Utils package. You may need to replace the single quotes with double ones to accommodate Windows' lack of abilities.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q35826440.txt"
:: first method
SET /a count=0
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO SET "line=%%a"&GOTO got1
:got1
SET "line=%line:"=%"
IF NOT DEFINED line ECHO method 1: %count% found&GOTO method2
IF "%line:~-1%"=="," SET /a count+=1
SET "line=%line:~0,-1%"
GOTO got1
:: second method
:method2
SET /a count=-1
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO SET "line=%%a"&GOTO got2
:got2
SET "line=%line:"=%"
SET "line=%line:;=%"
SET "line=%line: =%"
SET "line=%line:,=x,x%"
FOR %%a IN (%line%) DO SET /a count+=1
ECHO method 2: %count% found
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
I used a file named q35826440.txt containing your data for my testing.
Two methods - both read the first line to line, then removes any " characters.
The first then mechanically loops, checking whether the last character is a comma, counting if it is and removing the last character until the string found is empty.
The second replaces all ; and Space characters (for good measure, Tab could be removed too) and then replacing commas with x,x.
The result is that the only separators left are commas, and there will be 1 more item in the list so formed than there are commas.
Hence, start the counter at -1 and increment for each element found in the list.
Next solution (similar to Magoo's second method) seems to treat even ˙cmd˙ and .bat poisonous characters supposed in input file:
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "infile=D:\bat\SO\files\35826440input.txt" change to suit your circumstances
set /A "commacount=-1"
for /F "usebackq delims=" %%G in ("%infile%") do (
set "line=%%G"
call :parseline
if /I not "%~1"=="/all" goto :continue
)
:continue
echo script continues here
ENDLOCAL
exit /B
:parseline
rem treat unbalanced doublequote in next line
set "lineToParse=%line:"=§%"
set "lineToParse=%lineToParse:,=","%"
set /A "commacount=-1"
for %%g in ("%lineToParse%") do (
set /A "commacount+=1"
rem echo %line%, !commacount!, %%g
)
echo %commacount% "%line%"
goto :eof
Output (with input file listing):
==> D:\bat\SO\35826440.bat
1 "12345,Bhavik"
script continues here
==> D:\bat\SO\35826440.bat /all
1 "12345,Bhavik"
2 "12323,Bhavik,Sanghvi"
3 "12323,Bhavik,Sanghvi,three"
0 "zero"
1 ",1 leading"
2 ",,2 leading"
1 "trailing,"
2 "2 trailing,,"
2 "2 middle,,mid"
4 "!OS!,!,!!,!!!,exclamations"
4 "%OS%,%,%%%,%%,percents"
8 "&,|,>,<,",",;,=,miscelaneous"
0 "unbalanced"doublequote"
script continues here
==> type D:\bat\SO\files\35826440input.txt
12345,Bhavik
12323,Bhavik,Sanghvi
12323,Bhavik,Sanghvi,three
zero
,1 leading
,,2 leading
trailing,
2 trailing,,
2 middle,,mid
!OS!,!,!!,!!!,exclamations
%OS%,%,%%%,%%,percents
&,|,>,<,",",;,=,miscelaneous
unbalanced"doublequote
==>
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'm new to batch scripting and have a question. I was wondering if it's possible to search a .txt file by requirements and take data specified and copy into a new .txt file?
Like if I have 50 lines with 9 digit numbers and a bunch of other crap I don't need after them can I say,
"For any line beginning with a 1,2,3,4,5,6,7,8,or 9...take the first 9 digits and copy them into a new file, for all lines in the file???"
I thought this would be easier than trying to delete all the other stuff. Let me know if you know anything about how to do this! Thanks.
Here's an example of what one line looks like:
123456789#example
and I just need to extract the 9 digit numbers from about 50 lines of this.
You can use FINDSTR to filter out all lines that do not start with 9 digits. Then FOR /F can read the result, line by line. A variable is set, and a substring operation preserves just the first 9 digits.
#echo off
setlocal enableDelayedExpansion
(
for /f %%A in (
'findstr "^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]" yourFile.txt'
) do (
set "ln=%%A"
echo !ln:~0,9!
)
)>newFile.txt
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
(
FOR /f "delims=" %%a IN (q24824079.txt) DO (
SET "line=%%a"
REM set DIGITS to the first 9 characters of LINE
SET "digits=9!line:~0,9!"
FOR /L %%z IN (0,1,9) DO SET "digits=!digits:%%z=!"
IF NOT DEFINED digits ECHO(!line:~0,9!
)
)>newfile.txt
GOTO :EOF
I used a file named q24824079.txt containing data for my testing.
Produces newfile.txt
You did not specfy what to do if the line was all-digits but has fewer than 9 characters. I chose to report that line.
Hopefully this helps getting the job done:
#echo off
setlocal enabledelayedexpansion
for /f %%e in (emails.txt) do (
echo Email: %%e
for /f "delims=# tokens=1" %%b in ("%%e") do (
set BEGIN=%%b
echo Name: !BEGIN!
set FIRST=!BEGIN:~0,1!
echo First char: !FIRST!
set /a NUMERIC=!FIRST!+0
echo Converted to number: !NUMERIC!
if !FIRST!==!NUMERIC! echo Yippieh!
echo.
)
)
Instead of echo Yippieh! append the email (%%e) to a file, e.g. like
echo %%e >> output.txt