Batch file to insert string in exact position in file txt - windows

I have a test.txt file like this:
sylvester, stallone, 35,20, florida;
brad, pitt, 40,25, california;
sean, connery, 15,80, london;
I have to create a new one in which the surname begins with the 15th column and the name in the 30th.
I would like to do it with a batch file.
What I have managed to do is this:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "tokens=1,2 delims=," %%G IN (test.txt) DO (
SET "line=%%H"
SET "spaces= "
ECHO (!spaces!!line!!spaces!%%G
)
) >> output.txt
pause
But in this way %%G does not begin always from the same position, it depends on how many characters has %%H. And more, does not write on output.txt but it makes me see the results on the batch window.
I know it's probably a trivial question, but I'm new to programming.

#echo off
setlocal enabledelayedexpansion
del output.txt
set "spaces= " :: 15 spaces
(FOR /F "tokens=1,2 delims=, " %%G IN (test.txt) DO (
SET "line=%spaces%%%H %spaces%"
set "line=!line:~0,29!"
echo !line:~0,29!%%G
)) >output.txt
add 14 spaces in front of the surname (to let surename start at 15) and append another 15 spaces (to get a cumulated length of at least 29). Then trim it to the first 29 characters and append the name (at Pos 30).
(added a space to the delims for proper handling)

Related

Take text from a text file and put each line into a variable

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

How to extract the numbers after a character in windows batch files

Hi I do need to extract the last part of a string after the last dot
Example:
1.2.37 ==> I need the 37
1.2.567 ==> I need the 567
as you can see the number of characters after the dot is not fixed so expressions like
base=%fullver:~0,-2%
Can't be used. How can I achieve this?
#echo off
setlocal enableextensions disabledelayedexpansion
set "fullver=1.2.456"
for %%a in ("%fullver:.=\%") do set "base=%%~na"
echo %base%
The trick is to replace the dots with backslashes, process the string as a path and retrieve the name of the last element in it.
Alternatively, if all the elements need to be retrieved, instead of a for, a for /f is used to tokenize the variable using the dots as separators
#echo off
setlocal enableextensions disabledelayedexpansion
set "fullver=1.2.456"
for /f "tokens=1-3 delims=." %%a in ("%fullver%") do (
set "major=%%a"
set "minor=%%b"
set "build=%%c"
)
echo [%major%] [%minor%] [%build%]
I found the following question which actually tokenizes the string.
How to split a string in a Windows batch file?
May be you can try using this to delimit it with "." and take the last value stored in the string variable. Not sure if there is a simple way, but this works.
Here is an edited Version to fit your Needs:
#echo off
setlocal ENABLEDELAYEDEXPANSION
REM Set a string with an arbitrary number of substrings separated by semi colons
set teststring=1.2.5.234
for /f "tokens=1 delims=." %%a IN ("!teststring!") DO set firststring=%%a
echo !firststring!
REM Do something with each substring
:stringLOOP
REM Stop when the string is empty
if "!teststring!" EQU "" goto END
for /f "delims=." %%a in ("!teststring!") do set substring=%%a
REM Now strip off the leading substring
:striploop
set stripchar=!teststring:~0,1!
set teststring=!teststring:~1!
if "!teststring!" EQU "" goto stringloop
if "!stripchar!" NEQ "." goto striploop
goto stringloop
:END
echo !substring!
endlocal
I prefer MC ND's answer if you are looking for only the last node, or if you know how many nodes there are.
Here is a method to capture all nodes if the total number of nodes is unknown:
#echo off
setlocal enableDelayedExpansion
set "fullver=1.2.456"
:: Parse each node and store in an "array"
set cnt=0
for %%A in (%fullver:.= %) do (
set /a cnt+=1
set "node.!cnt!=%%A"
)
:: Show the results
for /l %%N in (1 1 %cnt%) do echo node.%%N = !node.%%N!
Another solution! This one gets the first and last parts of the string:
#echo off
setlocal
set "testString=1.2.5.234"
set "first="
for %%a in ("%testString:.=" "%") do (
if not defined first set "first=%%~a"
set "last=%%~a"
)
echo First: %first%
echo Last: %last%
As a bonus, this method correctly process special Batch characters that may appear in the string, excepting wild-cards.
You can use the below command to achieve what you want.
base=%fullver:~~4,3%
4 implies 4th digit i.e., 5 and 3 implies 3 digits from 4.
The output will be
567

Batch for insert/replace in a txt file in a fixed position

I need to replace, using a Batch file (.bat), a blank character, placed always in a fixed position (column 13) of each line in a .txt file, with another fixed character.
What kind of function can I use?
Example of my file:
1000588141025 00LEOTOURING SRL VIA FILADELFO CASTRO,1 LENTINI
I'd like to have:
1000588141025A00LEOTOURING SRL VIA FILADELFO CASTRO,1 LENTINI
#ECHO OFF
:: version 1 - "replace regardless"
SETLOCAL ENABLEDELAYEDEXPANSION
(
FOR /f "delims=" %%a IN (q26733113.txt) DO (
SET "line=%%a"
ECHO(!line:~0,13!A!line:~14!
)
)>newfile.txt
:: version2 - "replace only if space found in position"
SETLOCAL ENABLEDELAYEDEXPANSION
(
FOR /f "delims=" %%a IN (q26733113.txt) DO (
SET "line=%%a"
IF "!line:~13,1!"==" " (ECHO(!line:~0,13!A!line:~14!) ELSE (ECHO(%%a)
)
)>newfile2.txt
GOTO :EOF
I used a file named q26733113.txt containing your data for my testing.
Produces newfile.txt and newfile2.txt - the first changing column - well 14 in normal counting, as indicated in your test data - regardless of the content of column 14. The second only replaces column 14 with the A if it was a space, otherwise leaves it as-is.
Don't worry about the seeming-unbalanced parentheses. echo( has special properties - te parenthesis isn't counted...
Using REPL.BAT:
type "file.txt"|repl "^(.{12}) " "$1A" >"file.txt.new"
move /y "file.txt.new" "file.txt" >nul

How to read and find the largest value from .csv with the use of window batch

In my .csv file,
abc,10/24/2013,ABC
cede,5/1/2013,ABCk
cdeh,7/27/2014,ABCf
cdedsf,1/27/2014,gfABC
.
.
.(1xx more lines with similar text)
I would like to find the latest date in the middle field (e.g. 7/27/2014 in above case) and save to a variable named as "latest_date".
However, I do not know how to read the specific field from a .csv file and find the latest date with such format(M/D/Y).
Can anyone teach me?
This simpler method should run faster:
#echo off
setlocal EnableDelayedExpansion
set latest_num=0
for /F "tokens=2-4 delims=,/" %%a in (theFile.csv) do (
set /A "new_num=((%%c*100)+%%a)*100+%%b"
if !new_num! gtr !latest_num! (
set latest_num=!new_num!
set latest_date=%%a/%%b/%%c
)
)
echo Latest date: %latest_date%
#echo off
setlocal enableextensions disabledelayedexpansion
for /f "tokens=1-3 delims=/ " %%a in (
' cmd /q /v:on /c "for /f "tokens^=2-4 delims^=^,/" %%a in (data.csv) do (set /a "x^=%%c*10000+%%a*100+%%b" >nul & echo(^!x:~0,4^!/^!x:~4,2^!/^!x:~-2^!)" ^| sort /r '
) do set "last_date=%%b/%%c/%%a" & goto done
:done
echo %last_date%
How does it work?
The input file is readed via a for /f loop (the inner one). Each record is tokenized, using the commas and slashes as delimiters. This leaves the tokens 2 to 4 as the elements of the date. This elements are normalized (month and days have one or two digits, years are at the end) with some arithmetics to get a yyyy/mm/dd date, and the resulting dates are echoed. This list of dates is sorted in inversed order (so the greatest date is in the first record).
As the process in defined as a pipe (each process inside a pipe run in a separate cmd instance), and as the left part of the pipe requires delayed expansion enabled, the for /f that reads the file is executed inside its own instance of cmd with the adecuated configuration: echo off (/q) and delayed expansion active (/v:on).
The sorted list, will be readed with another for /f loop (the outer one), that will tokenize the retrieved data, separating again the year, month and day, so the final variable have the required format (mm/dd/yyyy). As the greatest date is in the first record, once it is retrieved and the value assigned to the variable, a goto jump to a label is executed to skip the rest of the records.
To see it clear, this is the same code, more readable, but separated in steps and using a temporary file
#echo off
setlocal enableextensions enabledelayedexpansion
set "tempFile=%temp%\%~nx0.%random%.tmp"
( for /f "tokens=2-4 delims=,/" %%a in (data.csv) do (
set /a "x=%%c*10000+%%a*100+%%b"
echo(!x:~0,4!/!x:~4,2!/!x:~-2!
)
)> "%tempFile%"
for /f "tokens=1-3 delims=/ " %%a in (
' type "%tempFile%" ^| sort /r '
) do set "last_date=%%b/%%c/%%a" & goto done
:done
echo %last_date%
del /f /q "%tempFile%" >nul 2>nul
endlocal
The inner loop in original code is now the first loop. File is readed by the for, date elements extracted (see tokens and delims), date normalized (set /a arithmetics) and the list saved to a temporary file
The outter loop in original code is the second one here. The file is readed with a type command, the data piped to sort /r and the resulting lines are tokenized by the for command to reformat the date.
Edited to adapt to comments
Aacini is right, his code is faster, but given that i just started this way, .... Anyway, the changes in this code can be translated to his solution
This should handle differences in date fields (aditional spaces and aditional initial 0) and missing fields.
#echo off
setlocal enableextensions disabledelayedexpansion
for /f "tokens=2 delims=:" %%a in (
'cmd /q /v:on /c "for /f "delims^=" %%z in (data.csv) do for /f "tokens^=1-3 delims^=^," %%w in (" %%~z ") do if not "%%~y" equ "" for /f "tokens^=1-3 delims^=/ " %%a in ("%%~x") do (set /a "x^=%%c*10000 + 100%%a %% 100*100 + 100%%b %% 100" >nul & echo(^!x^!:%%~x)" ^| sort /r '
) do set "latest_date=%%a" & goto done
:done
echo %latest_date%
The inner for loops :
for %%z will read lines from file
for %%w will tokenize the readed line with an aditional space at the start and end of the line to prevent problems with adjacent delimiters removal.
for %%a handles the date normalization and outputs the calculated value used for sort and the readed date.
The outer for %%a loop will split the retrieved record to separate the calculated value from the readed date.
In the CMD the variable are displayes in alphabetical order and from the smaller to the bigger value.
So we transform all your dates in variables like this : set #142707=7/27/2014
Then looping against a set # we take the last value who is the latest date.
#echo off
setlocal enabledelayedexpansion
for /f "tokens=2 delims=," %%a in (data.csv) do call:checkDate %%a
for /f "tokens=2 delims==" %%a in ('set #') do set $LatestDate=%%a
echo The Latest Date : [!$LatestDate!]
exit/b
:CheckDate
set $out=
set "$Date=%1"
set "$Date=%$Date:/= %
for %%b in (%$Date%) do (
set $val=0%%b
set $out=!$val:~-2!!$out!)
set #!$out!=%1

Batch Scripting:search file, extract numbers, and copy into new file

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

Resources