Batch script to extract part of a string - batch-file

I need a batch script that will read in another batch script (batch2) and:
look for the string "configout:" OR "configin:"
If it encounters one of these two strings, extract what's after it until the string ".xml"
copy paste it in a new text file.
and do this for each line of batch2.
For exemple:
If this is my first line in the batch script
/configin:%faxml%fm_sellin_in.xml /configout:%faxml%transco_fm_sellin_out%col_transco%.xml /inputfile:
I should have this in my text file:
%faxml%fa_sellin_in.xml
%faxml%transco_fm_sellin_out%col_transco%.xml
I have seen a good code in Here:
for /f "tokens=1-2 delims=~" %%b in ("yourfile.txt") do (
echo %%b >> newfile.txt
echo removed %%a)
but i don't know how to adapt it to my specific case.

Why not replace all the /configin and /configout with newlines? -
(Replace string with a new line in Batch)
For example
setlocal EnableDelayedExpansion
set "str=/configin:%%faxml%%fm_sellin_in.xml /configout:%%faxml%%transco_fm_sellin_out%%col_transco%%.xml /inputfile:"
set str=!str:/configin^:=^
!
set str=!str:/configout^:=^
!
Now, !str! would contain
fm_sellin_in.xml
transco_fm_sellin_out.xml /inputfile:
Then, you could use the for loop to extract the strings
for /f "tokens=1,2 delims=. " %%a in ("!str!") do ()
this for loop iterates through each line and splits each line with the and . characters.
So %%a is your file name and %%b is the extension.
then
if [%%b]==[xml] (echo %%a.%%b>>mytextfile.txt)
We will do this for all the lines of batch2.
And the finished code is
setlocal EnableDelayedExpansion
for /f "delims=" %%c in (batch2.txt) do (
set str=%%c
set str=!str:/configin^:=^
!
set str=!str:/configout^:=^
!
for /f "tokens=1,2 delims=. " %%a in ("!str!") do (if [%%b]==[xml] (echo %%a.%%b>>mytextfile.txt))
)

Related

How to create a batch file on Windows to write out strings from a text file based on a substring and new line?

folks!
I'm not sure if this is a very simple task or a very complicated one, but either way I'm struggling with it. Suppose I have a text file like this:
11111FOO
11111BAR
22222ZOOM
33333FOO
11111CAR
I want to figure out a command line in windows that I can plop into a batch file that will pull out text strings from this file and push them to a new file. I would pass in the leading string to search for, and it would take everything from the end of that string to the next new line.
So using the above example, if I said the leading string was 11111, I would get a new text file that looked like this:
FOO
BAR
CAR
Everything else would be ignored.
Thanks!
If there are no potential poison characters in the input file then perhaps this would suffice:
#(For /F "UseBackQ Delims=" %%A In ("input.txt") Do #(Set "an=%%A"
For /L %%B In (%%A 1 %%A) Do #Call Echo %%an:*%%B=%%))>"output.txt"
Magoo's additions:
#Echo Off
(For /F "UseBackQ Delims=" %%A In ("q46858215.txt") Do (Set "an=%%A"
For /L %%B In (%%A 1 %%A) Do Call Echo %%an:*%%B=%%))>"Output1.txt"
If "%~1"=="" GoTo :Next
(For /F "Delims=" %%A In ('FindStr/BLC:"%~1" "q46858215.txt"') Do (
Set "an=%%A"
For /L %%B In (%%A 1 %%A) Do Call Echo %%an:*%%B=%%))>"Output2.txt"
:Next
(For /F "UseBackQ Delims=" %%A In ("q46858215.txt") Do (Set "an=%%A"
For /L %%B In (%%A 1 %%A) Do Echo %%B))>"Output3.txt"
I used a file named q46858215.txt containing OP's data for my testing.
Produces three output files:
Output1.txt : Compo's original
Output2.txt : filtered to isolate lines beginning with (first parameter to routine)
Output3.txt : Compo's original in reverse, showing the numbers isolated

Batch script -> find a sentence and replace it by a new one

I'm working on a DOS script in order to search a line and replace it into files from a specific folder. Here is what i have already done :
#echo off
setlocal enableextensions disabledelayedexpansion
set "search=#Interceptors({ RuntimeExceptionInterceptor.class }^)"
set "replace=#Interceptors({ RuntimeExceptionInterceptor.class, ReportInterceptor.class, CorrelationIdInterceptor }^)"
set "textFile=C:\Utilisateurs\a669884\Documents\test.txt"
for %%a in (*.txt) do (
echo "%%a"
for /f "Delims=" %%i in (%%a ^& break ^> %%a) do (
set "line=%%i "
setlocal enabledelayedexpansion
>>%%a echo(!line:%search%=%replace%!
endlocal
)
)
Problem is that my first line is not replace by the new one, the new line is added under it like that :
#Interceptors({ RuntimeExceptionInterceptor.class })
#Interceptors({ RuntimeExceptionInterceptor.class, ReportInterceptor.class, CorrelationIdInterceptor })
Do you know why my first line isn't replaced? Thanks a lot
Seb
Not sure what setting textfile has to do with the routine - it's not used.
Your original code produced a complaint that & was not found and created an empty file for me.
Changing the for to
for /f "Delims=" %%i in ('type "%%a" ^& break ^> "%%a"') do (
seemed to make the substitution, given the one line (partial?) of sourcefile you've provided, plus a few dummy lines.
execute the type... with the filenames enclosed in quotes to ensure correct operation with separators, replacing the file; substitute as specified.

Copy lines based on a word using bat script from a text file

I have a huge text file from which I just need copy only certain lines. I have written a bat script for the same. I navigate through the text file and consider only those lines which are prefixed by the word "ResponseCode". The bat file is as below:
#ECHO OFF & setlocal enabledelayedexpansion
if exist E:\output.txt del E:\output.txt
for /f "delims=" %%i in (E:\test.txt) do (
set "line0=%%i"
set "line=!line0:*ResponseCode=!"
if not "!line0!"=="!line!" (
for /f %%j in ("!line!") do set "line=%%j"
if not defined $a!line! (
set "$a!line!=!line!"
(echo(!line0!) >> E:\output.txt
)
)
)
But when I run the above script it copies just one line from test.txt instead of four as expected and write it to output.txt. How can I make it copy all the four lines that contain ResponseCode as the prefix word?
findstr /L "ResponseCode" "E:\test.txt" will return all lines that contain ResponseCode literally.
The returned lines can be easily redirected to your output file by appending >> "E:\output.txt".
The following code parses the output of findstr and outputs everything after ResponseCode:
setlocal EnableDelayedExpansion
rem.> "E:\output.txt"
for /F "delims=" %%L in ('findstr /L "ResponseCode" "E:\test.txt"') do (
set "LINE=%%L" & set "LINE=!LINE:*ResponseCode=!" & echo !LINE!
) >> "E:\output.txt"
endlocal
Note that findstr performs a case-sensitive search as /I is not given; however, removal of everything to the (first) occurrence of ResponseCode (by expansion !LINE:*ResponseCode=!) is accomplished in a case-insensitive manner!
Could you do this instead?
findstr /b ResponseCode "E:\test.txt" >>"E:\output.txt"
The /b tells it to only output the line if "ResponseCode" exists at the beginning of the line.

Batchfile: read last lines from logfiles and copy them to a new file

This is my first posting so if the format is not as it supposed to be please excuse me for this. (Suggestions for
improvement are welcome.)
I am trying to create a batchfile that will read last lines from logfiles and copy them to a new file.
Until now I have found here a way to read the last line.
Code would be something like:
for /f %%i in ('find /v /c "" ^< someFile.txt') do set /a lines=%%i
set /a startLine=%lines% - 1
more /e +%startLine% someFile.txt > lastLines.txt
The above code works for one file at a time. What I need is to read the last line from all files in a known list and add this line to a new .csv file.
I have been using the following code for getting the 4th entry in the logfiles but it returns every line of every logfile:
for /f %%x in (%list%) do for /f "delims=.txt, tokens=4" %%i in (%%x.txt) do echo %%x, %%i >> output.csv
What I would need is a sort of combination of both but I don't know how to combine them and make the complete last line be copied to the .csv file.
===
#Magoo:
Thanx for your reaction.
In every logfile can be 1 to >100 lines with comma separated information. Something like:
"LOGON,6-1-2015,12:43:39,USERNAME,HOSTNAME,,,,192.168.209.242,00:21:5A:2E:64:5E"
The last code with the 4th entry was used to get a list of all accounts that had logged in to the computers. This code gave me a very large list of all logon/logoff events on all computerlogs I checked in %list%.
In %list$ I had all the names of logfiles I wanted to be checked. This returned all lines.
For a new batchfile I need only the last logon/logoff entry and I want the whole last line.
So I have a .txt file with the hostnames of all computers I need to examine.
This .txt file will be read line by line via the variable %list%.
From every logfile I need only the last line copied to an output file.
===
I just tried the solution offered by JosefZ. Unfortunately this does not work for me yet. No lastlines are copied to the resultfile. In the code I removed the extra entry for possible lastlines for there are no empty lines in the logs, I also added an entry for the hostname I want to be available in the result. JosefZ had the filename there:
#ECHO OFF >NUL
#SETLOCAL enableextensions disabledelayedexpansion
type nul>output.csv
set "list=_listing.txt"
for /F "tokens=*" %%x in ('type "%list%"') do (
set "host=%%~x"
for /F "tokens=*" %%G in ('type "%%~x"') do set "lastline=%%G"
call :lline
)
:endlocal
#ENDLOCAL
goto :eof
:lline
set "filename=.\logs\%filename:&=^&%.txt"
echo %host%,%lastline%>>output.csv
goto :eof
The resultfile shows only the hostnames. I'll puzzle some more with this but all tips are welcome!
===
Got it!!!
#ECHO OFF >NUL
#SETLOCAL enableextensions disabledelayedexpansion
type nul>output.csv
set "list=_listing.txt"
for /F "tokens=*" %%x in ('type "%list%"') do (
set filename= :: *empty previous filename*
set lastline= :: *empty previous lastline*
set "host=%%~x"
set "filename=.\logs\%host%.txt" :: *creating the filename from path+hostname+extention*
for /F "tokens=*" %%G in ('type "%filename%"') do set "lastline=%%G"
call :lline
)
:endlocal
#ENDLOCAL
goto :eof
:lline
echo %host%,%lastline%>>output.csv
goto :eof
Your approach with line numbering could fail if a file has more trailing empty lines. Fortunately for /F loop ignores (does not iterate) empty lines; let's put to use this feature: in the script used next practices:
disabledelayedexpansion to allow ! in file names
set "list=_listing.txt" where the _listing.txt contains list of file names (full path and extension .txt including), one file name on one line: got by dir /b /s *.txt>_listing.txt
type nul>files\output.csv to empty the output file (optional)
set "lastline=!!!file empty!!!" to initialize variable %lastline%; could be set "lastline=" as well
call :lline to process variables %filename% and %lastline%
set "filename=%filename:&=^&%" to allow & in file names
The script is as follows:
#ECHO OFF >NUL
#SETLOCAL enableextensions disabledelayedexpansion
type nul>files\output.csv
set "list=_listing.txt"
for /F "tokens=*" %%x in ('type "%list%"') do (
set "filename=%%~x"
set "lastline=!!!file empty!!!"
rem the whole line
for /F "tokens=*" %%G in ('type "%%~x"') do set "lastline=%%G"
rem the fourth token only
rem for /F "tokens=4" %%G in ('type "%%~x"') do set "lastline=%%G"
call :lline
)
:endlocal
#ENDLOCAL
goto :eof
:lline
set "filename=%filename:&=^&%"
echo %filename% %lastline%
rem >>files\output.csv
goto :eof
Sample _listing.txt file:
d:\bat\files\1exclam!ation.txt
d:\bat\files\2exc!lam!ation.txt
d:\bat\files\11per%cent.txt
d:\bat\files\12per%cent%.txt
d:\bat\files\17per%Gcent.txt
d:\bat\files\18per%%Gcent.txt
d:\bat\files\21ampers&nd.txt
d:\bat\files\22ampers&&nd.txt
Output:
d:\bat>lastlines
d:\bat\files\1exclam!ation.txt 0 15.01.2015 1:52:28.48 -15072 20465
d:\bat\files\2exc!lam!ation.txt 6 15.01.2015 1:52:28.50 3250 16741
d:\bat\files\11per%cent.txt -8 15.01.2015 1:52:28.50 -3692 27910
d:\bat\files\12per%cent%.txt !!!file empty!!!
d:\bat\files\17per%Gcent.txt 0 15.01.2015 1:52:28.56 14508 12374
d:\bat\files\18per%%Gcent.txt 1 15.01.2015 1:52:28.56 30540 26959
d:\bat\files\21ampers&nd.txt 15.01.2015 1:22:50.18
d:\bat\files\22ampers&&nd.txt 15.01.2015 1:22:50.18
Honestly, all that ballast is for (possibly) trailing empty lines in files and for (possibly) ! and & in file names only; all could be done with
for /f %%x in (%list%) do for /f "skip=%startLine% tokens=4" %%i in (%%x) do echo %%x, %%i >> output.csv
You should use a simple FOR to iterate a list of values, not FOR /F.
Something like the following should work:
#echo off
setlocal enableDelayedExpansion
>>output.csv (
for %%F in (
"file1.log"
"file2.log"
"file3.log"
etc.
) do (
for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1
more +!skip! %%F
)
)
The quotes around the file names are there in case you get a name with spaces.
You could use your LIST variable if it looks something like
set LIST="file1.log" "file2.log" "file3.log" etc.
#echo off
setlocal enableDelayedExpansion
set LIST="file1.log" "file2.log" "file3.log" etc.
>>output.csv (
for %%F in (%LIST%) do (
for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1
more +!skip! %%F
)
)
If any of your file names contain the ! character, then you must toggle delayed expansion ON and OFF within your loop. Otherwise the delayed expansion will corrupt the names when %%F is expanded.
#echo off
setlocal disableDelayedExpansion
set LIST="file1.log" "file2.log" "file3.log" etc.
>>output.csv (
for %%F in (%LIST%) do (
for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1
setlocal enableDelayedExpansion
more +!skip! %%F
endlocal
)
)

I am writing a .bat program to find and replace text in a file without changing its position

I am writing a .bat program that will find and replace text in a file. The problem that I am having is that it is removing blank lines and left justifying the other lines. I need the blank lines to remain and the new text to remain in the same location. Here is what I have wrote, and also the result. Can anybody please help.
program:
#ECHO OFF
cls
cd\
c:
setLocal EnableDelayedExpansion
For /f "tokens=* delims= " %%a in (samplefile.tx) do (
Set str=%%a
set str=!str:day=night!
set str=!str:winter=summer!
echo !str!>>samplefile2.txt)
ENDLOCAL
cls
exit
samle File:
this line is the first line in my file that I am using as an example.This is made up text
the cat in the hat
day
winter
below is the result:
this line is the first line in my file that I am using as an example.This is made up text
the cat in the hat
night
summer
I need the lines, spaces and new text to remain in the same position while making the text replacement. Please help
Your use of "tokens=* delims= " will trim leading spaces. Instead, use "delims=" to preserve leading spaces.
FOR /F always skips empty lines. The trick is to insert something before each line. Typically FIND or FINDSTR is used to insert the line number at the front of each line.
You can use !var:*:=! to delete the the line number prefix from FINDSTR.
Use echo(!str! to prevent ECHO is off message when line is empty
It is more efficient (faster) to redirect only once.
#echo off
setlocal enableDelayedExpansion
>samplefile2.txt (
for /f "delims=" %%A in ('findstr /n "^" samplefile.txt') do (
set "str=%%A"
set "str=!str:*:=!"
set "str=!str:day=night!"
set "str=!str:winter=summer!"
echo(!str!
)
)
This still has a potential problem. It will corrupt lines that contain ! when %%A is expanded because of the delayed expansion. The trick is to toggle delayed expansion on and off within the loop.
#echo off
setlocal disableDelayedExpansion
>samplefile2.txt (
for /f "delims=" %%A in ('findstr /n "^" samplefile.txt') do (
set "str=%%A"
setlocal enableDelayedExpansion
set "str=!str:*:=!"
set "str=!str:day=night!"
set "str=!str:winter=summer!"
echo(!str!
endlocal
)
)
Or you could forget custom batch entirely and get a much simpler and faster solution using my JREPL.BAT utility that performs regular expression search and replace on text. There are options to specify multiple literal search/replace pairs.
jrepl "day winter" "night summer" /t " " /l /i /f sampleFile.txt /o sampleFile2.txt
I used the /I option to make the search case insensitive. But you can drop that option to make it case sensitive if you prefer. That cannot be done easily using pure batch.
#ECHO Off
SETLOCAL
(
FOR /f "tokens=1*delims=]" %%a IN ('find /n /v "" q27459813.txt') DO (
SET "line=%%b"
IF DEFINED line (CALL :subs) ELSE (ECHO()
)
)>newfile.txt
GOTO :EOF
:subs
SET "line=%line:day=night%"
SET "line=%line:winter=summer%"
ECHO(%line%
GOTO :eof
Thi should work for you. I used a file named q27459813.txt containing your data for my testing.
Produces newfile.txt
Will not work correctly if the datafile lines start ].
Revised to allow leading ]
#ECHO Off
SETLOCAL
(
FOR /f "delims=" %%a IN ('type q27459813.txt^|find /n /v "" ') DO (
SET "line=%%a"
CALL :subs
)
)>newfile.txt
GOTO :EOF
:subs
SET "line=%line:*]=%"
IF NOT DEFINED line ECHO(&GOTO :EOF
SET "line=%line:day=night%"
SET "line=%line:winter=summer%"
ECHO(%line%
GOTO :eof

Resources