0

I have an executable, say, process.exe, that reads from stdin and outputs a processed version of it to stdout. What I would like to create is a batch file wrapper that I can call in its place so that only part of the stdin gets processed. Specifically, the part after a certain keyword is detected.

For example, let's say process.exe works by outputting the same lines that are given to it, just with a star added to the end. (It is of course much much complicated, but just as an example.) So if I run it with the following input:

apple
banana
cantaloupe
date

I get

apple*
banana*
cantaloupe*
date*

What I want to do is create a batch file so that only the lines occurring after a line containing my special keyword are processed. So, if the keyword is "keyword" and my input is:

apple
banana
keyword
cantaloupe
date

I want

apple
banana
keyword
cantaloupe*
date*

Note that lines before the keyword are still output to stdout, they are just not passed to process.exe. How can I accomplish this? Ideally, I would like to avoid writing to disk, since the input I will be supplying could be very large. Now, I found out I can use for /F "tokens=*" %%a in ('findstr /n $') do ( in order to loop through stdin line by line, but it seems findstr consumes the entire input, so I can't pass any of it to process.exe...

If such a thing is impossible with Windows Batch Files, how about Powershell?

Paul Accisano
  • 1,416
  • 1
  • 14
  • 25
  • 1
    "*it seems findstr consumes the entire input, so I can't pass any of it to process.exe...*" - looks like it doesn't here - https://stackoverflow.com/a/6980605/478656 . Yes it's very possible in powershell. `$words | foreach-object -begin { $KeywordSeen = $false } -process { if (-not $keywordSeen) { $_ } else { $_ | process.exe }; if ($_ -eq 'keyword') { $KeywordSeen = $true } }` or similar. – TessellatingHeckler May 31 '17 at 22:26
  • 1
    What have you tried so far, what part do you have problems with? – aschipfl May 31 '17 at 22:31
  • 1
    In PowerShell you could read the source in as a here-string, split on the keyword, pass the first part to stdout, split the second part on new lines, and pass those to process.exe. `$fileInput = (get-content $filepath -raw) -split $keyword; $fileInput[0]; $fileInput[1] -split '[\r\n]+'|Process.exe` – TheMadTechnician May 31 '17 at 22:44

1 Answers1

1
@echo off
setlocal
set "process="
(
for /f "delims=" %%a in (filename) do (
 if "%%a"=="keyword" set "process=Y"
 if defined process (process %%a) else (echo %%a)
)
)>outputfilename
goto :eof

Naturally, you could add /i to the keyword-detect if case-insensitivity is required, you could change keyword to %~1 to input the keyword on the command-line. Switch the order of the ifs if you want to not send keyword to process

And don't call the batch file process.bat.

Magoo
  • 77,302
  • 8
  • 62
  • 84