0

Over 10 years ago, Mike asked the question "How can I use a file in a command and redirect output to the same file without truncating it?" for bash. I would like to ask the same question for the Windows command processor.

The requirement is doing this without creating any temporary files. Thus, AFAIK, answers involving piping will not be suitable.

This is my current code, but the output will always be 0 bytes, likely because the command processor creates the output redirection before reading the source file:

findstr.exe /v /c:"test string" file_name >file_name

1 Answers1

1

Unlike *nix commands, there are no one line solutions on Windows for something like this.

a Possible solution, which will also cater for blank lines:

@echo off
set "file=file_name"

for /f "delims=" %%i in ('type "%file%" ^| findstr.exe /v /c:"test string" ^| find /n /v "^"  ^& break ^> "%file%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    set "line=!line:*]=!"
    >>"%file%" echo(!line!
    endlocal
)

You have to note that any string that contains the substring test string will also be excluded.

Gerhard
  • 22,678
  • 7
  • 27
  • 43
  • Thanks Gerhard. That's a very clever solution. Utilizing more than 1 line of code is no problem at all. What is an issue, though, is that I think your code will generate temp files due to the piping, which won't work for this specific situation. Although they will get deleted by the OS, the requirement is to not create any temp files. – RockPaperLz- Mask it or Casket Jan 27 '22 at 11:27
  • 1
    What gives you the idea that piping creates temporary files? Piping happens in memory, not on disk. It has to do with the way `stdin` is read from the `stdout` of the previous command. – Gerhard Jan 27 '22 at 11:33
  • My recollection might be outdated, but I thought, for piping, Windows wrote a temporary file containing the output of the file on the left side of the pipe, then passed it to the application on the right side of the pipe. I seem to recall this causing several issues in the early days of Windows. It's possible I'm remembering incorrectly or that Microsoft changed it at some point. – RockPaperLz- Mask it or Casket Jan 27 '22 at 11:45
  • 1
    Not at all. Piping does not touch the disk, it is purely in memory. – Gerhard Jan 27 '22 at 11:46
  • 1
    Piping in DOS and Win95/98/ME does use a temporary file... – Anders Jan 27 '22 at 13:20
  • 1
    @Anders, but this is not DOS, which in Windows used `command.com`. This is windows `cmd` which is `cmd.exe`. Besides, if you still use Win95/98/ME you should consider retiring :) – Gerhard Jan 27 '22 at 13:23
  • 1
    @RockPaperLz-MaskitorCasket, open up task manager and click on the details tab. Watch the memory usage of the process as it reads in a very large file using a `FOR /F` command. It always stores it in memory. – Squashman Jan 27 '22 at 14:26