Delete certain line in text file using batch - batch-file

I have a txt file . I want to delete line 4 and line 5 only.
Before
Line1
Line2
Line3
Line4 (need to delete)
Line5 (need to delete)
Line6
After
Line1
Line2
Line3
Line6

#echo off
setlocal EnableDelayedExpansion
call :CopyLines < input.txt > output.txt
move /Y output.txt input.txt
goto :EOF
:CopyLines
rem Copy lines 1, 2 and 3
for /L %%i in (1,1,3) do (
set "line="
set /P "line="
echo(!line!
)
rem Omit lines 4 and 5
for /L %%i in (4,1,5) do set /P "line="
rem Copy the rest
findstr "^"
exit /B

Try below code which would do exactly what you require :
#echo off
cls
setlocal EnableDelayedExpansion
set /a count=0
if exist neww.txt (del /s /q neww.txt)
for /f "tokens=*" %%a in (onee.txt) do (
set /a count+=1
if !count! EQU 4 (
echo do nothing
)else if !count! EQU 5 (
echo do nothing
)else (
echo %%a>>neww.txt
)
)
move /y neww.txt onee.txt

Related

Assign each line of the text file to a variable to verify numbers are in sequence in windows batch script

I'm learning windows batch-file script and creating my own scripts to practice the coding but kind of hit a block while try find whether the numbers in a text file is in sequence or not.I have two files,one file(file.txt) contains the number of lines in file_received.txt. The file_received.txt content is below:
1021
1022
1023
1024
1025
1027
1028
I'm building a script to test whether all the numbers in the text file are in sequence .so as a first step I'm trying to extract each line of the file_received to be assigned to a variable through if / for loop but the if command loop assigning all the lines to the variable num from file_received.txt at the same time. Is it possible to assign first line of the file to variable num and increment it as the if loops increment?
setlocal EnableDelayedExpansion
rem assign the number of lines to a variable
set /P var=<C:\files.txt
for /F "tokens=1" %%a in ("%var%") do echo.%%a
rem assign the first variable to var1
set /P var1=<C:\files_received_sequence.txt
for /F "tokens=1" %%a in ("%var1%") do echo.%%a
set /a x=1
:while
if %x% leq %var% (
echo %x%
rem assigning each line to the variable num inside the if loop and will be used in comparison and reser
for /F "tokens=%x%" %%i in (C:\files_received.txt) do set num=%%i
echo %num%
set /a x+=1
goto :while
)
echo test :D
the output is as below in loop 1 the entire file content is assigned to the variable num and from loop 2 to 7 the last number is assigned.
C:\>setlocal EnableDelayedExpansion
C:\>set /P var= 0<C:\files.txt
C:\>for /F "tokens=1" %a in ("7 ") do echo.%a
C:\>echo.7
7
C:\>set /P var1= 0<C:\files_received.txt
C:\>for /F "tokens=1" %a in ("1021") do echo.%a
C:\>echo.1021
1021
C:\>set /a x=1
C:\>if 1 LEQ 7 (
echo 1
for /F "tokens=1" %i in (C:\files_received.txt) do set num=%i
echo
set /a x+=1
goto :while
)
1
C:\>set num=1021
C:\>set num=1022
C:\>set num=1023
C:\>set num=1024
C:\>set num=1025
C:\>set num=1027
C:\>set num=1028
ECHO is on.
C:\>if 2 LEQ 7 (
echo 2
for /F "tokens=2" %i in (C:\files_received.txt) do set num=%i
echo 1028
set /a x+=1
goto :while
)
2
1028
Here's the logic I'd use to test that each number is in sequence incrementing by one (and only one) each time:
#Echo off & Setlocal EnableDelayedExpansion
Set "ln="
For /F "Delims=" %%i in (C:\file_received.txt) Do (
If Not "!ln!"=="" For /F "UseBackQ Delims=" %%v in (`"Set /A Nx=!ln!+1"`) Do (If Not "%%i"=="%%v" (Echo/OoS:!ln!/%%i & Goto :False))2> Nul
Set "ln=%%i"
)
Echo/True
Exit /B 0
:False
Echo/False
Exit /B 1
Here is a version that will highlight the item not in sequence. Do note, that it will test sequence only, in other words ensure the previous result is lower than the next
#echo off & setlocal enabledelayedexpansion
set rev=-1
for /f "delims=" %%a in (files_received.txt) do for %%i in (%%a) do (
if %%i leq !rev! (
echo %%i Out of sequence
) else (
echo %%i
set rev=%%i
)
)
besides you don't use delayed expansion (although you have enabled it), your logic is far too complicated:
#echo off
setlocal enabledelayedexpansion
set last=-1
for /f %%a in (t.txt) do (
if %%a lss !last! (
echo not in sequence
goto :eof
)
set "last=%%a"
)
echo all in sequence.
the variable !last! holds the value from the previous iteration of the loop.
(Depending on your needs, you may want to replace lss with leq)

print exact all characters from lines from one file to one file in batch file

Here i am printing line no 1 to 5 from a file to another file.its working fine but one small issue that the lines are trimming from left side,i do not want to trim,it should be same as the input file.
infile.txt:
<RCO-XXX-AGENT>
<CREATED>2018-06-28 10:19:09</CREATED>
<FORMAT>
<VARIABLE>
<EOR>/010</EOR>
<EOC>/009</EOC>
<CTR>5</CTR>
code:
echo off
setlocal enabledelayedexpansion
call :Print_Lines > outfile.txt
endlocal
:Print_Lines
setlocal enabledelayedexpansion
set cur=0
for /f "delims==" %%i in (infile.txt) do (
set /a cur=cur+1
if !cur! geq 1 (
if !cur! leq 5 (
for /f "tokens=*" %%j in ( "%%i") do (
echo %%j
)
)
)
)
endlocal
exit /b 0
goto :eof
outfile.txt:
<RCO-XXX-AGENT>
<CREATED>2018-06-28 10:19:09</CREATED>
<FORMAT>
<VARIABLE>
<EOR>/010</EOR>
The second loop is useless
It should work :
echo off
setlocal enabledelayedexpansion
call :Print_Lines > outfile.txt
endlocal
:Print_Lines
setlocal enabledelayedexpansion
set cur=0
for /f "delims==" %%i in (infile.txt) do (
set /a cur=cur+1
if !cur! geq 1 (
if !cur! leq 5 (
echo %%i
)
)
)
endlocal
exit /b 0
goto :eof
In your exemple, the spaces at left are not printed because they are considered as delimiter character
I would suggest this method:
#Echo Off
Set "Num=5"
<"infile.txt" (For /L %%A In (1,1,%Num%) Do (Set "_="
Set /P "_="
SetLocal EnableDelayedExpansion
Echo=!_!
EndLocal))>"outfile.txt"
Where you can adjust the value to Num as necessary.

Batch scripting: read lines and execute a command after every other line read

Suppose I have a text file like this
node1.log
node2.log
node3.log
node4.log etc...
I want to read each line by line and execute
alan.exe node1.log node2.log
alan.exe node3.log node4.log
etc..
What is the best way to accomplish this?
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%a in (file.txt) do (
if not defined line (
set "line=%%a"
) else (
ECHO alan.exe !line! %%a
set "line="
)
)
Give this a try. File.txt will have your log file names.
#echo off
setlocal enabledelayedexpansion
FOR /F "delims=" %%G IN ('find /c /v "" ^<file.txt') DO SET NUM=%%G
SET /A NUM=NUM / 2
< file.txt (
FOR /L %%G IN (1,1,%NUM%) DO (
SET /P LINE1=
SET /P LINE2=
echo mypgm.exe !LINE1! !LINE2!
)
)
pause
Output
mypgm.exe node1.log node2.log
mypgm.exe node3.log node4.log
mypgm.exe node5.log node6.log
Press any key to continue . . .
Remove the word echo and replace mypgm.exe with the program you want to run. The echo is just in there for the proof of concept.
Like this:
#echo off
setlocal enabledelayedexpansion
set args=
set n=2
for /f "tokens=*" %%x in (file.txt) do (
set args=!args! %%x
set /a n -= 1
if !n! EQU 0 (
alan !args!
set args=
set n=2
)
)

How to replace text in last 20 lines of a text file?

#ECHO OFF & SETLOCAL
copy /Y C:\LOG.DIR LOG.DIR
set "old=INACTIVE"
set "new=ACTIVE"
FOR /f %%a IN ('^<log.DIR find /v /c ""') DO SET /a length=%%a
SET /a length-=20
SETLOCAL ENABLEDELAYEDEXPANSION
<log.DIR (
FOR /l %%a IN (1,1,%length%) DO (
SET "line="
SET /p "line="
ECHO !line!
))>newfile
ENDLOCAL
for /f "skip=%length% delims=" %%a in (LOG.DIR) do (
set "str=%%a"
SETLOCAL ENABLEDELAYEDEXPANSION
set "str=!str:%old%=%new%!"
>>newfile ECHO !str!
endlocal
)
I just want to change last 20 lines from INACTIVE to ACTIVE. And if file has less than 20 lines, all lines of file should be changed.
But currently the new file is empty, if the number of lines in file is less than 20.
What to change to avoid an empty new file?
#echo off
setlocal enableextensions enabledelayedexpansion
copy /y c:\log.dir log.dir
set "old=INACTIVE"
set "new=ACTIVE"
for /f %%a in ('^<log.dir find /v /c ""') do set /a "length=%%a"
if %length% gtr 20 ( set /a "startPoint=length-20+1" ) else ( set "startPoint=1" )
<log.dir (
for /l %%a in (1,1,%length%) do (
set "line="
set /p "line="
if not defined line (
echo(
) else if %%a lss %startPoint% (
echo(!line!
) else (
echo(!line:%old%=%new%!
)
)
)>newfile
endlocal
Adjust where to start depending of the file length. If you have more than 20 lines, the starting point is calculated. If you have less lines, process from the start.

copy lines from a text file to another

i have two text files
file1 has the following lines
line1
line2
hello-hai-1
hello-2-hai
3-hai-hello
hello
and file 2 has
line4
line3
hello-hai-5
hello-7-hai
6-hai-hello
hai
hello-4
what i want to do is copy all the lines which contain both hello and hai in file2 and overwrite it on those lines in file1, the no. of lines may or may not be equal. but all the hello-hai lines are together in both files
the current code i use is
setlocal enabledelayedexpansion
for /f "tokens=1*delims=:" %%i in ('^<file2 essentials\findstr.exe /n "hello"') do set "#%%i=%%j"
(for /f "delims=" %%i in (file1) do (
set "line=%%i"
if not "!line!"=="!line:hello=!" (
if not "!line!"=="!line:hai=!" (
if not defined flag (
for /f "tokens=1*delims==" %%a in ('set "#"') do echo(%%b
set "flag=true"
)
) else echo !line!
) else echo(!line!
))>output.txt
this copies all hello lines over the hello-hai lines in file1, i want to know how to add the word hai to the search in first file
#echo off
setlocal EnableDelayedExpansion
rem Find lines with both strings in file2
set i=0
for /F "delims=" %%a in ('findstr "hello" file2 ^| findstr "hai"') do (
set /A i+=1
set "file2[!i!]=%%a"
)
rem Merge file1 with the found lines in file2
set i=0
(for /F "delims=" %%a in (file1) do (
set "line=%%a"
if "!line:hello=!" neq "!line!" (
if "!line:hai=!" neq "!line!" (
set /A i+=1
for %%i in (!i!) do echo !file2[%%i]!
) else (
echo !line!
)
) else (
echo !line!
)
)) > output.txt
EDIT: New version added
Previous solution achieve a line-by-line replacement that works even if the matching lines are not together in any file (file merge), but requires that the number of matching lines be the same in both files. The new simpler version below works in the way requested by the OP:
#echo off
setlocal EnableDelayedExpansion
(for /F "delims=" %%a in (file1) do (
set "line=%%a"
if "!line:hello=!" neq "!line!" (
if "!line:hai=!" neq "!line!" (
if not defined flag (
findstr "hello" file2 | findstr "hai"
set flag=true
)
) else (
echo !line!
)
) else (
echo !line!
)
)) > output.txt
Try this:
#echo off &setlocal
set "tf1=%temp%\~%random%1"
set "tf2=%temp%\~%random%2"
set "tf3=%temp%\~%random%3"
set "tf4=%temp%\~%random%4"
set "pt=hello"
set "pu=hai"
<file1 findstr /lin "%pt%">"%tf1%"
<"%tf1%" findstr /li "%pu%">"%tf2%"
<file2 findstr /li "%pt%">"%tf3%"
<"%tf3%" findstr /li "%pu%">"%tf4%"
for /f "usebackqdelims=:" %%i in ("%tf2%") do (
if not defined st set "st=%%i"
set "fi=%%i"
)
set /a st-=1
<file1 (
for /l %%i in (1,1,%st%) do (
set "line="
set/p "line="
setlocal enabledelayedexpansion
echo(!line!
endlocal
))>"%tf1%"
<file1>"%tf3%" more +%fi%
copy /a "%tf1%"+"%tf4%"+"%tf3%"=output.txt>nul
del "%temp%\~*"
type output.txt
output is:
line1
line2
hello-hai-5
hello-7-hai
6-hai-hello
hello
#ECHO OFF
SETLOCAL
SET searching=Y
(
FOR /f "delims=" %%i IN (file1.txt) DO (
ECHO %%i|FIND "hello"|FIND "hai" >NUL
IF ERRORLEVEL 1 (ECHO(%%i) ELSE (
IF DEFINED searching TYPE "file2.txt"|FIND "hello"|FIND "hai"
SET "searching="
)
)
)>output.txt
TYPE output.txt
GOTO :EOF
Here's a version without tempfiles. It simply reproduces lines from file1 that don't contain BOTH of the target strings. When BOTH are found in the same line, it outputs all of those lines in file2 that contain both strings. The searching flag is used to ensure that the file2 lines are only output once.
It won't reproduce blank lines or lines that begin ;. Could be made to do so if required.

Resources