Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
Lowsun
- Posts: 29
- Joined: 14 Apr 2019 17:22
#1
Post
by Lowsun » 10 Jun 2022 12:56
Hello, I'm looking to print to a file but replacing the same line each time. I thought of trying to output a carriage return but that did not work
Code: Select all
@ECHO OFF
:MAIN
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F %%A in ('COPY "%~f0" NUL /Z') DO SET "CR=%%A"
(FOR %%G in (1 2 3) DO (
<NUL SET /P "=%%G !CR!"
))>output.txt
PAUSE
EXIT /B
So for example right now it outputs
whereas the result I would like would be
Is this possible without using
Code: Select all
(<NUL SET /P "=%%G !CR!")>output.txt
Thanks
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#2
Post
by aGerman » 10 Jun 2022 14:10
The CR is a control character. The console host as well as other virtual terminal emulators have a rendering engine. Whenever it finds a supported control character in the character stream, it will execute a piece of code that performs the associated action behind the scenes. In case of a CR character, it's a piece of code that moves the cursor to the beginning of the line in the window. However, there is no rendering engine in place if you redirect the stream to a file. In the consequence, everything including the CR characters is just written through.
If you now open the file in a text editor, it'll depend on the used editor app how the CR characters are rendered. Modern editors may consider to see a file created on a classic Mac OS where the CR is the newline character. But, howsoever the file content is rendered, it doesn't change anything on the fact that the file still contains the CR characters along with anything else that has been redirected.
I hope this sheds some light on the behavior, and it explains why you can't just use the CR to overwrite the line in a file.
Steffen
-
Lowsun
- Posts: 29
- Joined: 14 Apr 2019 17:22
#3
Post
by Lowsun » 10 Jun 2022 15:55
Thanks, appreciate your explanation. Was just hoping there was some cool way to get this to work, but I was totally off the map
-
Aacini
- Expert
- Posts: 1914
- Joined: 06 Dec 2011 22:15
- Location: México City, México
-
Contact:
#4
Post
by Aacini » 11 Jun 2022 11:02
Do you want to
move the file pointer of a redirected text file? If so, you could do that using my FilePointer.exe auxiliary program. Download it from
this thread. If you move the file pointer to file begin each time a CR is output, then the next output will be placed at the beginning of the file,
replacing any previous output.
Perhaps if you describe your requirement with more detail we could help you better.
-
Lowsun
- Posts: 29
- Joined: 14 Apr 2019 17:22
#5
Post
by Lowsun » 11 Jun 2022 11:22
@Aacini yes that is exactly what I would like to do, to move the file pointer all the way to the start. Hence a loop like this (example)
Code: Select all
(FOR %%G in (1, 2, 3) DO (
ECHO %%G
))>output.txt
output.txt would just have
Your FilePointer.exe is a good solution, though I was wondering if a pure Batch solution is also possible. The reason for all this is because I have a program reading the Batch output.txt and as time goes on, output.txt grows very big, and my program begins to slow down, but in the mean time I will use your FilePointer.exe. Thanks!
-
miskox
- Posts: 630
- Joined: 28 Jun 2010 03:46
#6
Post
by miskox » 12 Jun 2022 04:47
...to move the file pointer all the way to the start.
Why don't you just write a new file each time?
Saso
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#7
Post
by aGerman » 12 Jun 2022 06:20
Depends on whether you want to overwrite a line in a file that already has some content to be kept.
Using FilePointer.exe:
Code: Select all
@echo off &setlocal
>"_out.txt" echo first line
<"_out.txt" FilePointer.exe 0 0 /E
set /a "pos=%errorlevel%"
>>"_out.txt" (
for /l %%i in (1,1,100) do (
FilePointer.exe 1 %pos%
echo second line with #%%i
)
)
>>"_out.txt" echo third line
The second line is written a hundred times where the first line is never touched. However, the way I wrote this example is not foolproof. It only works if the length of the second line does never decrease. There's a TruncateFile.exe in Antonio's tool chain though.
Antonio, you may consider to add an option to FilePointer.exe (like /T) to truncate the file after the set pointer position. Like
for the above example.
Steffen
-
Aacini
- Expert
- Posts: 1914
- Joined: 06 Dec 2011 22:15
- Location: México City, México
-
Contact:
#8
Post
by Aacini » 12 Jun 2022 09:44
aGerman wrote: ↑12 Jun 2022 06:20
. . .
Antonio, you may consider to add an option to FilePointer.exe (like /T) to truncate the file after the set pointer position. Like
for the above example.
Steffen
My design philosophy for these auxiliary programs has always been to keep them as simple as possible. Duplicating the function of TruncateFile.exe in FilePointer.exe is not consistent with this philosophy...
Antonio
-
Aacini
- Expert
- Posts: 1914
- Joined: 06 Dec 2011 22:15
- Location: México City, México
-
Contact:
#9
Post
by Aacini » 12 Jun 2022 09:47
Lowsun wrote: ↑11 Jun 2022 11:22
@Aacini yes that is exactly what I would like to do, to move the file pointer all the way to the start. Hence a loop like this (example)
Code: Select all
(FOR %%G in (1, 2, 3) DO (
ECHO %%G
))>output.txt
output.txt would just have
Well, if you do this:
Code: Select all
FOR %%G in (1, 2, 3) DO (
>output.txt ECHO %%G
)
... you will get in output.txt just the line with 3
Antonio
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#10
Post
by aGerman » 12 Jun 2022 10:34
Creating processes in a loop causes performance issues. That's been the reason for my proposal. Only having one new process per iteration rather than two could be quite beneficial.
However, I agree that consistently keeping the tools dedicated to only one certain purpose each is a valid reason for leaving them like they are.
Steffen
-
Lowsun
- Posts: 29
- Joined: 14 Apr 2019 17:22
#11
Post
by Lowsun » 12 Jun 2022 12:44
@Aacini that is true, however since I'm using this code in a large loop that is being read by another program, it slows down by quite a bit. I was just wondering if there was a cool trick to do it without redirecting to a new file each time and preferably in pure Batch.