Merge every 2nd line with previous line in batch scripting - windows

I used the following code, but set Content is blank in my case. Please help. Thanks.
set content=
for /f "delims=" %%i in (fileA.txt) do set content=%%i
for /f "delims=" %%i in (FileA.txt) do set content=%content% %%i
ECHO %content%> result.txt
FileA.txt
test
A
Testing
B
Expected Output:
test A
Testing B

You need a single for command to process all lines and this simple logic: if it is the first line read, store it; else show the stored first line and the second one AND delete the first line, so the same logic be used in all line pairs:
#echo off
setlocal EnableDelayedExpansion
set "firstLine="
(for /F "delims=" %%a in (FileA.txt) do (
if not defined firstLine (
set "firstLine=%%a"
) else (
echo !firstLine! %%a
set "firstLine="
)
)) > result.txt

Your two for work independently (the second starts when the first is finished).
Your first loop gets the last line of the file and then the second adds every line of the textfile to the variable (there is a limit for variable length and you will soon reach it with this method).
The empty variable at the end is due to lack of using delayed expansion.
Work with a single for and an alternating flag instead:
#echo off
setlocal enabledelayedexpansion
set flag=0
(for /f "delims=" %%i in (FileA.txt) do (
if !flag!==0 (
<nul set /p ".=%%i "
) else (
echo %%i
)
set /a "flag=(flag+1) %% 2"
))>result.txt
Note: due to batch/cmd limitations, this may have some problems (line length, special characters

We need '#echo off' statement to not to print code on every execution of the program and only echo statements, 'rem' is to mention the line is a comment. 'SETLOCAL EnableExtensions EnableDelayedExpansion' is need to enable ! statements to resolve the variables.
#echo off
rem this for loop reads the file FileA.txt line by line by specifying delims= (nothing)
rem then checks the condition if the line is even line or not, if odd then adding it to myVar variable
rem if even then printing both earlier odd with the current even line to the result.txt file.
set myVar=
set nummod2=0
set /a i=0
rem creating an empty file on everytime the program runs
copy /y nul result.txt
SETLOCAL EnableExtensions EnableDelayedExpansion
for /f "delims=" %%a in (FileA.txt) do (
set /a i=i+1
set /a nummod2=i%%2
if !nummod2!==0 (
echo !myVar! %%a
) else (
set myVar=%%a
)
) >> result.txt;
echo 'Done with program execution. Result saved to result.txt in the same folder of this batchfile'
rem pause

Related

Reading line by line from one file and write to another file using batch script

In below code i am tring to fetch the line no of string "AXX0000XXXA" from file data.txt,then fetching line by line and printing target.txt file,in between if the line reach the find line no i am adding one more line from file temp.txt.The code is working fine with the less nos of records(tested with 150 lines-File Size 100 kb),but when i am processing with 50K records(File Size 25MB) it is taking more then 25 minutes to process.could you please help me how i will process same in less time.
#echo off
setlocal enabledelayedexpansion
for /f "delims=:" %%a in ('findstr /n "AXX0000XXXA" "C:\Users\23456\Desktop\data.txt"') do (set find_line=%%a)
set /a counter=0
for /f "usebackq delims=" %%b in (`"findstr /n ^^ C:\Users\23456\Desktop\data.txt"`) do (
set curr_line=%%b
set /a counter=!counter!+1
if !counter! equ !find_line! (
type temp.txt >> target.txt
)
call :print_line curr_line
)
endlocal
:print_line
setlocal enabledelayedexpansion
set line=!%1!
set line=!line:*:=!
echo !line!>>target.txt
endlocal
Your code uses three Batch file constructs that are inherently slow: call command, >> append redirection and setlocal/endlocal, and these constructs are executed once per each file line! It would be faster to include the subroutine into the original code to avoid the call and setlocal commands, and an echo !line!>>target.txt command imply open the file, search for the end, append the data and close the file, so it is faster to use this construct: (for ...) > target.txt that just open the file once. An example of a code with such changes is in Compo's answer.
This is another method to solve this problem that may run faster when the search line is placed towards the beginning of the file:
#echo off
setlocal enabledelayedexpansion
for /f "delims=:" %%a in ('findstr /n "AXX0000XXXA" "C:\Users\23456\Desktop\data.txt"') do (set /A find_line=%%a-1)
call :processFile < "C:\Users\23456\Desktop\data.txt" > target.txt
goto :EOF
:processFile
rem Duplicate the first %find_line%-1 lines
for /L %%i in (1,1,%find_line%) do (
set /P "line="
echo !line!
)
rem Insert the additional line
type temp.txt
rem Copy the rest of lines
findstr ^^
exit /B
This should create target.txt with content matching data.txt except for an inserted line taken from tmp.txt immediately above the line matching the search string, AXX0000XXXA.
#Echo Off
Set "fSrc=C:\Users\23456\Desktop\data.txt"
Set "iSrc=temp.txt"
Set "sStr=AXX0000XXXA"
Set "fDst=target.txt"
Set "iStr="
Set/P "iStr="<"%iSrc%" 2>Nul
If Not Defined iStr Exit/B
Set "nStr="
For /F "Delims=:" %%A In ('FindStr/N "%sStr%" "%fSrc%" 2^>Nul') Do Set "nStr=%%A"
If Not Defined nStr Exit/B
( For /F "Tokens=1*Delims=:" %%A In ('FindStr/N "^" "%fSrc%"') Do (
If "%%A"=="%nStr%" Echo %iStr%
Echo %%B))>"%fDst%"
I have made it easy for you to change your variable data, you only need to alter lines 3-6.
I have assumed that this was your intention, your question was not clear, please accept my apologies if I have assumed incorrectly.

Redirecting contents of a file to a variable in command prompt

I have a file "file.txt" which contains the output of "dir /s /b *.c"
I want to write this whole content of file.txt in a single variable .
Any ideas?
The usual way to treat questions like this one is to reply: "What do you want this for?". However, your question is pure and simple, so here is the answer. The Batch file below not just store the contents of file.txt in a single variable, but it also later process the variable value as individual lines.
EDIT: I added the method to extract individual lines from the variable value as substrings.
#echo off
setlocal EnableDelayedExpansion
rem Create variables with LF and CR values:
set LF=^
%empty line 1/2, don't remove%
%empty line 2/2, don't remove%
for /F %%a in ('copy /Z "%~F0" NUL') do set CR=%%a
rem Store the contents of file.txt in a single variable,
rem end each line with <CR><LF> bytes
set "variable="
for /F "delims=" %%a in (file.txt) do (
set "variable=!variable!%%a!CR!!LF!"
)
rem 1- Show the contents of the variable:
echo !variable!
rem 2- Process the contents of the variable line by line
echo/
set i=0
for /F "delims=" %%a in ("!variable!") do (
set /A i+=1
echo Line !i!- %%a
)
rem Get the starting position and length of each line inside the variable
set /A i=0, lastStart=0
for /F "delims=:" %%a in (
'(cmd /V:ON /C set /P "=^!variable^!" ^& echo/^) ^<NUL ^| findstr /O "^^"'
) do (
set /A len[!i!]=%%a-lastStart-2, i+=1
set /A start[!i!]=%%a, lastStart=%%a
)
set "len[0]="
set "start[%i%]="
set /A lastLine=i-1
rem 3- Extract individual lines from the variable contents as substrings
:getNumber
echo/
set "num="
set /P "num=Enter line number (nothing to end): "
if not defined num goto end
if %num% gtr %lastLine% echo Invalid number & goto getNumber
for /F "tokens=1,2" %%i in ("!start[%num%]! !len[%num%]!") do (
echo Line %num%- !variable:~%%i,%%j!
)
goto getNumber
:end
You must note that Batch variables can only store a maximum of 8K characters.
No. But you can go through the lines one by one.
for /f "delims=" %A in (file.txt) do echo %A
Maybe say what you are trying to achieve. Knowledge of C won't help you in batch because it's contary for historical reasons.
You can use set /p:
set /p foo=<file.txt
See also this question.
Batch-Script is a very limited tool with a primitive support for multi-line variables (with specific hacks that will not work as expected for this sceneario but if you are interested see this).
The only reasonable solution is to move to a capable language, which is every else less Batch-Script.

For loop only loops once

I have a very weird error occurring in my Batch script where a For loop is only looping once when it should loop many more times (at least 10 times).
Can you tell me why my For loop is only looping once and how I can fix it?
#ECHO off
CLS
SETLOCAL
SET macroFolder=_PLACE_4DM_FILES_HERE
REM the following for loop only loops once when it should be looping more
REM because theres over 10 *.4dm files in the folder??
for /r ./%macroFolder% %%i in ("*.4dm") do SET "file=%%i" (
echo %file%
REM Note I need to store %%i in a variable so I can edit it later
REM And placing %%i in a variable within the for loop results in
REM the var being empty for some reason. For eg
SET file=%%i
ECHO file is %file%
REM Prints "file is "
)
ECHO.
PAUSE
ENDLOCAL
You have (at least) two problems. The first is that you seem to be mixing the bracketed and non-bracketed form of the for statement:
for /r ./%macroFolder% %%i in ("*.4dm") do SET "file=%%i" (
blah blah
)
In that case, the non-bracketed bit is executed per-loop-iteration but the bracketed bit executes after loop exit. You can see this with:
for /r ./%macroFolder% %%i in ("*.4dm") do echo 1 (
echo 2
)
which outputs (in my case where there are three 4dm files):
1 (
1 (
1 (
2
Your second problem is that %% variable expansion is done before the command executed and the for command is a multi-line one, from the for to the closing ) bracket. Any variables you need expanded, that have been set within the loop, need to be done with delayed expansion.
Start with this:
#SETLOCAL enableextensions enabledelayedexpansion
#ECHO off
CLS
SET macroFolder=4dmfiles
for /r ./%macroFolder% %%i in ("*.4dm") do (
SET file=%%i
ECHO file is !file!
)
ECHO.
PAUSE
ENDLOCAL
and you'll see (for my three files):
file is C:\Users\Pax\Documents\4dmfiles\1.4dm
file is C:\Users\Pax\Documents\4dmfiles\2.4dm
file is C:\Users\Pax\Documents\4dmfiles\3.4dm

replacing a specific line of the file using DOS

I have a XML file and I need to replace a perticular line say 7th line with the my own line using DOS command. How to do this?
My proposal is based on the fact you identify the line by its number and not by its content
#echo OFF
REM Say LINE 7 to be removed
SETLOCAL ENABLEDELAYEDEXPANSION
SET LOWER=6
SET UPPER=8
SET INDEX=0
SET MYLINE="this is my new line"
SET OUTFILE=%~n1.new%~x1
>%OUTFILE% (
for /F "tokens=*" %%L in (%1) do (SET /A INDEX += 1
IF !INDEX! LEQ %LOWER% (echo %%L) ELSE break
)
echo %MYLINE%
more +%UPPER% %1
)
echo off needed since we do a massive redirect
ENABLEDELAYEDEXPANSION
needed for the counter in the loop
You just pass the xml file as an argument to the script.
HTH

Store file output into variable

I want to store the output of text file into a variable, so I can pass the whole file as parameter.
I am using Windows 2003 Server.
The text files have multiple lines like:
10.20.210.100 fish
10.20.210.101 rock
I was using:
Set /P var=<file.txt
It reads only the first line of the file.
I tried with FOR loop also but it assigned only the last line to the variable.
There is no simple way to get the complete content of a file into one variable.
A variable has a limit of ~8100 length.
And it is complicated to get CR/LF into a variable
But with a FOR-loop you can get each single line.
Try a look at batch script read line by line
EDIT:
To get each line in a single variable you can use this
#echo off
SETLOCAL EnableDelayedExpansion
set n=0
for /f "delims=" %%a IN (example.txt) do (
set /a n+=1
set "line[!n!]=%%a"
echo line[!n!] is '%%a'
)
set line
or to get all in only one variable (without CR/LF)
#echo off
SETLOCAL EnableDelayedExpansion
set "line="
for /f "delims=" %%a IN (example.txt) do (
set "line=!line! %%a"
)
echo !line!
Jeb’s script is working perfect, But if you echo %line% it contains each line no of line in file times. And if you use echo !Line! ,it contain one !line! also with other line. I did a little modification in script and now I am getting expected result.
#echo off
SETLOCAL EnableDelayedExpansion
set "line="
for /f "delims=" %%a IN (example.txt) do (
set "line1=%%a"
set "line=!line1! and %%a"
)
echo !line!
or
echo %line%
Now you will get same result in bot cases.

Resources