I want to make it so that the empty lines are also outputted. For eg, this is my example.txt file.
Hello
This is a text file. Hello World!
And my code to run it is,
for /f "delims=" %%a in (%cd%\example.txt) DO (
echo. %%a
)
But it doesnt show the empty lines and instead shows it like
Hello
This is a text file. Hello World!
How do I make it so it shows the empty line too? Thanks!
FOR /F ignores empty lines, but you can use findstr to prefix each line with a line number, then there aren't empty lines anymore.
setlocal EnableDelayedExpansion
FOR /F "delims=" %%L in ('findstr /N "^" "%~dp0\example.txt"') DO (
set "line=%%L"
set "line=!line:*:=!" & rem Remove all characters to the first colon
echo(!line!
)
The problem with delayed expansion is that it destroys all ! and ^ characters from your file.
Therefore, you could toggle the mode.
setlocal DisableDelayedExpansion
FOR /F "delims=" %%L in ('findstr /N "^" "%~dp0\example.txt"') DO (
set "line=%%L"
setlocal EnableDelayedExpansion
set "line=!line:*:=!" & rem Remove all characters to the first colon
echo(!line!
endlocal
)
Related
For example I have a text file test.txt that contains like this:
Item1 $23 Item2 $24
Item3 $25
When I run this script:
#echo off
for /f "delims=$ tokens=1*" %%A in (test.txt) do echo %%B >> result.txt
The result is:
23 Item2 $24
25
I want the result is:
23
24
25
How should I repair the script?
Try the following script (see the explanatory rem remarks in the code):
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_IFILE=test.txt"
set "_OFILE=result.txt"
rem // Store line-break in variable:
(set ^"LF=^
%= blank line =%
^")
rem // Write to resulting file:
> "%_OFILE%" (
rem // Loop through lines of text file:
for /F "usebackq delims=" %%L in ("%_IFILE%") do (
rem // Store current line in variable:
set "LINE=%%L"
rem // Toggle delayed expansion to be able to write and read variable in same code block:
setlocal EnableDelayedExpansion
rem // Replace each `$` by line-break and loop over resulting lines skipping the first one:
for /F "skip=1" %%K in (^"!LINE:$^=^%LF%%LF%!^") do (
rem // Return first token of each line:
echo(%%K
)
endlocal
)
)
endlocal
exit /B
At first, this replaces every $ by a line-break, so the first line of test.txt becomes:
Item1
23 Item2
24
And the second one becomes:
Item3
25
Then it extracts the first SPACE- or TAB-separated token from each of the newly formed multi-line strings, skipping the first line, so only the numbers are returned.
I have decided to post this example batch-file to show a method of parsing each line and returning every other string, (doesn't work with poison characters).
#(For /F "UseBackQDelims=" %%A In ("test.txt")Do #(Set "i=0"
For %%B In (%%A)Do #(Set /A "i=(i+1)%%2"&Cmd /V:On /Q /C Exit !i!
If Not ErrorLevel 1 Echo %%B)))>"results.txt"
In your posted example code and 'wanted' result, you could probably use that idea to output the strings with their first character removed if it is a $.
#(For /F "UseBackQDelims=" %%A In ("test.txt")Do #(Set "i=0"
For %%B In (%%A)Do #(Set /A "i=(i+1)%%2"&SetLocal EnableDelayedExpansion
If !i! Equ 0 (Set "Val=%%B"&If "!Val:~,1!"=="$" (Echo !Val:~1!
)Else Echo %%B)&EndLocal)))>"results.txt"
This should do exactly what you want.
#echo off
setlocal enabledelayedexpansion
(for /f "usebackq tokens=* delims= " %%i in ("test.txt") do (
set "_br=%%i"
echo(!_br: =^
!
)
)>_tmp
(for /f "delims=$ tokens=*" %%a in ('type _tmp ^| find "$"') do echo %%a)>result.txt
Note that you must copy the script as is. The extract of the script as show below does the replacement of whitespace with new line and therefore cannot change at all, the position and the extra line must remain as is for this to work as intended.
echo(!_br: =^
!
This script just splits each word separated by a space and redirects it to a new file, we then specifically search for the words containing $ and redirect those hits only.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for /f "delims=" %%A in (test.txt) do (
for %%T in (%%A) do (
set "term=%%T"
if "!term:~0,1!"=="$" echo !term:~1!
)
)>> result.txt
endlocal
Read each line to %%A. Tokenise to %%T. Assign each token in turn to term, examine the first character and if $, echo the term, except the first character.
I found a example of what I wanted to do online, which was search a text file for a string and replace only that string and write out to a file. Which sort-of works...
The script does replace the correct text. But, its printing line numbers, which I don't want. However, if I remove the \n flag from findstr, it only prints lines containing data, and lines that aren't comments *(i.e. beginning with ";;").
How do I use findstr to print all the lines without the line numbers?
#echo off &setlocal
set "search=string to replace"
set "replace=replace string with me"
set "textfile=input.ini"
set "newfile=output.ini"
(for /f "delims=" %%i in ('findstr /n "^" "%textfile%"') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
))>"%newfile%"
type "%newfile%"
The /n switch is required to keep the empty lines, so if want the empty lines in input be copied to the output you should not remove /n switch from findstr otherwise you do not need findstr and can directly read file with FOR. instead you can remove the line numbers by this modified code of yours:
#echo off
setlocal
set "search=string to replace"
set "replace=replace string with me"
set "textfile=input.ini"
set "newfile=output.ini"
(for /f "tokens=1* delims=:" %%i in ('findstr /n "^" "%textfile%"') do (
if "%%j" NEQ "" (
set "line=%%j"
setlocal enabledelayedexpansion
echo(!line:%search%=%replace%!
endlocal
) else (
echo(
)
))>"%newfile%"
type "%newfile%"
Also there is no need for set "line=!line:%search%=%replace%!" you can directly pass !line:%search%=%replace%! to echo
Or you can get ride of findstr altogether and simply write the FOR loop as below but you will loos empty lines
(for /f "usebackq delims="eol^= %%i in ("%textfile%") do (
set "line=%%i"
setlocal enabledelayedexpansion
echo(!line:%search%=%replace%!
endlocal
))>"%newfile%"
Please note that in "usebackq delims="eol^= there must be no spaces between the quotation mark(") and eol. It is not a typo.
This is to disable the default eol character(;) so the lines that beginning semicolon(;) will not be ignored by FOR /F command
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))
)
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
I have this code to replace some text in JS file:
#echo off &setlocal
set "search=showLog: true"
set "replace=showLog: false"
set "textfile=globalsDebugTest.js"
set "newfile=new.js"
(for /f "delims=" %%i in ('findstr /n "^" "%textfile%"') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
))>"%newfile%"
type "%newfile%"
The problem with this script is that it adds a line number in every new line.
I just want to replace this string: "showLog: true" with this: "showLog: false".
Any idea how to do it?
for /f "tokens=1*delims=:" %%h in ('findstr /n "^" "%textfile%"') do (
(note the addition of a tokens= phrase, delims is assigned : and the loop metavariable is changed to h.)
adding the tokens= means the metavariable h receives the number before the delimiter (colon) and i the remainder of the line after the colon. This keeps the changes on one line.
Another option would be to simply drop the /n from the findstr which will have the consequence of removing all empty lines from the output.