Piped input and output to a batch file
Moderator: DosItHelp
Piped input and output to a batch file
Folks,
I wrote a simple batch file to take a file and add a prefix and a suffix to every line in the file. Example: "append pre suf file.ext"
:: append.bat
@echo off
SETLOCAL
set prefix=%~1
set suffix=%~2
set f=%~3
(for /f "tokens=1,* delims=:" %%a in (%f%) do (
(echo.%prefix% "%%a" %suffix%)
)) > temp.txt
rem move /y "temp.txt" "%f%"
EXIT /b
I would like to modify this to act on piped output from another command, add a prefix and a suffix to every line, and output it to the console or pipe to another command. For example: "dir /b > append pre suf" or "dir /b > append pre suf |findstr ..."
How do I do this? Thanks for your suggestions.
Cheers!
-Jason
I wrote a simple batch file to take a file and add a prefix and a suffix to every line in the file. Example: "append pre suf file.ext"
:: append.bat
@echo off
SETLOCAL
set prefix=%~1
set suffix=%~2
set f=%~3
(for /f "tokens=1,* delims=:" %%a in (%f%) do (
(echo.%prefix% "%%a" %suffix%)
)) > temp.txt
rem move /y "temp.txt" "%f%"
EXIT /b
I would like to modify this to act on piped output from another command, add a prefix and a suffix to every line, and output it to the console or pipe to another command. For example: "dir /b > append pre suf" or "dir /b > append pre suf |findstr ..."
How do I do this? Thanks for your suggestions.
Cheers!
-Jason
Re: Piped input and output to a batch file
You are not going to be able to do that without some type of stream editor like SED. They do make ports of it for Win32.
But your examples shows that you want to do this from the output of the DIR command which is easy enough with a FOR LOOP.
But your examples shows that you want to do this from the output of the DIR command which is easy enough with a FOR LOOP.
Code: Select all
@echo off
SETLOCAL
set prefix=%~1
set suffix=%~2
FOR /F "tokens=*" %%I in ('dir /b /a-d') do echo %prefix% %%I %suffix%
-
- Expert
- Posts: 442
- Joined: 01 Aug 2010 17:13
- Location: Canadian Pacific
- Contact:
Re: Piped input and output to a batch file
Squashman, that is incorrect...
Jason, working with the output of any command always involves for /f "..." %%a in ('...') do ....
Jason, working with the output of any command always involves for /f "..." %%a in ('...') do ....
Code: Select all
for /f "delims=" %%a in ('dir /b') do call "append.bat" prefix suffix "%%a"
Last edited by orange_batch on 23 Dec 2011 15:07, edited 1 time in total.
Re: Piped input and output to a batch file
Not understanding how you feel my response was incorrect.
You are not going to be able to use a PIPE to get the desired result he wants unless he would use something like SED or AWK. You would have to use a FOR Loop which is what I provided.
You are not going to be able to use a PIPE to get the desired result he wants unless he would use something like SED or AWK. You would have to use a FOR Loop which is what I provided.
-
- Expert
- Posts: 442
- Joined: 01 Aug 2010 17:13
- Location: Canadian Pacific
- Contact:
Re: Piped input and output to a batch file
Sorry, you're right about piping specifically, but your code echoes the file names with the prefix and suffix (not modifying the contents). What I mean is, it's possible to do what he asked using batch.
Jason, your code is a little wonky so I'll post a complete solution. This will overwrite your input file.
As a separate batch (append.bat):
Use with:
As a subroutine:
This version will not overwrite your input file:
Now to find a specific line...
And of course, to do something if the search query is successful would be...
Jason, your code is a little wonky so I'll post a complete solution. This will overwrite your input file.
As a separate batch (append.bat):
Code: Select all
@echo off
for /f "tokens=1* delims=:" %%a in ('type "%~3"^&type nul^>"%~3"') do echo(%~1 "%%a" %~2>>"%~3"
exit/b
Use with:
Code: Select all
for /f "delims=" %%a in ('dir /b') do call "append.bat" prefix suffix "%%a"
As a subroutine:
Code: Select all
@echo off
for /f "delims=" %%a in ('dir /b') do call :append prefix suffix "%%a"
pause
exit
:append
for /f "tokens=1* delims=:" %%a in ('type "%~3"^&type nul^>"%~3"') do echo(%~1 "%%a" %~2>>"%~3"
exit/b
This version will not overwrite your input file:
Code: Select all
@echo off
type nul>"temp.txt"
for /f "usebackq tokens=1* delims=:" %%a in ("%~3") do echo(%~1 "%%a" %~2>>"temp.txt"
exit/b
Now to find a specific line...
Code: Select all
type "temp.txt"|findstr ...
And of course, to do something if the search query is successful would be...
Code: Select all
for /f "delims=" %%a in ('type "temp.txt"^|findstr ...') do ...
Re: Piped input and output to a batch file
A batch file can process lines piped into it. I derived this solution from a jeb post on StackOverflow http://stackoverflow.com/a/6980605/1012053
Edit: bug fix - added missing quote
Dave Benham
Edit: bug fix - added missing quote
Code: Select all
@echo off
setlocal
set "prefix=%~1"
set "suffix=%~2"
for /f "delims=" %%A in ('findstr /n $') do (
set "ln="
set "ln=%%A"
setlocal enableDelayedExpansion
if defined ln set "ln=!ln:*:=!"
echo(!prefix! "!ln!" !suffix!
endlocal
)
Dave Benham
Last edited by dbenham on 04 Jan 2012 23:26, edited 1 time in total.
Re: Piped input and output to a batch file
That is pretty cool
Re: Piped input and output to a batch file
The Batch file below take the prefix and suffix from parameters 1 and 2. If the %3 parameter is given, then it is the name of the input file to process; otherwise the piped input is processed. Anyway, the output is always sent to the standard output (the screen) that is the way that a "filter program" must work.
Previous program ends at the first empty line. Although this point may be fixed when processing a file, there is no way for SET /P command to differentiate an empty line from the end of file when processing the piped input.
Code: Select all
@echo off
setlocal
set "prefix=%~1"
set "suffix=%~2"
if not "%3" == "" (
call :ProcessLines < "%3"
) else (
call :ProcessLines
)
goto :EOF
:ProcessLines
set line=:EOF
set /P line=
if "%line%" == ":EOF" exit /b
echo %prefix% %line% %suffix%
goto ProcessLines
Previous program ends at the first empty line. Although this point may be fixed when processing a file, there is no way for SET /P command to differentiate an empty line from the end of file when processing the piped input.
Re: Piped input and output to a batch file
I don't think SET /P is a good option in this case. The filter program should not terminate upon the first empty line.
Dave Benham
Dave Benham
Re: Piped input and output to a batch file
Yes you are right, but SET /P is the only way that a Batch file may behave like a "filter command": anycommand | aBatchFile.
Re: Piped input and output to a batch file
How does my posted code not work as a filter program? It is easily modified to take the 3rd argument as the optional input file
Dave Benham
Code: Select all
@echo off
setlocal
set "prefix=%~1"
set "suffix=%~2"
for /f "delims=" %%A in ('findstr /n $ %3') do (
set "ln="
set "ln=%%A"
setlocal enableDelayedExpansion
if defined ln set "ln=!ln:*:=!"
echo(!prefix! "!ln!" !suffix!
endlocal
)
Dave Benham
Re: Piped input and output to a batch file
Excuse me, perhaps I didn't expressed it correctly. SET /P is the only way a Batch file have to get piped input if it use built-in (cmd.exe internal) Batch commands only. If an external executable file is used, then anything is possible, right?
We used to use FINDSTR command for several purposes although it was originally designed to find strings in files. For example, we use FINDSTR to process blank lines in FOR command (inserting a line number that must be removed later) or to get piped input, like in this case.
I wrote a very small and fast program that just read bytes from stdin and sent they to stdout, so I called it PIPE. Additionally it insert a space in empty lines, so the process of this topic may be achieved in a simpler and faster way this way:My PIPE.COM program is only 69 bytes in size, so it is a very good replacement of FINDSTR to be used in these cases. If you are worried about where to get my program from, here it is; just copy the 69 bytes below to a file named PIPE.COM and it is ready to run:
ë2´)€ì!Í!ŠÐŠà€Ä!€ü.u.€þ+u)R²A€ê!´#€ì!Í!Z´#€ì!Í!Šò€Æ!´,€ì!Í!"ÀuôLÍ!ëã
You may first create a file called PIPE.TXT and then do a REN PIPE.TXT PIPE.COM. If someone is worried about the blank space inserted in empty lines, then PIPE program may be easily modified to insert a colon in every line, the same was as FINDSTR. I wrote this program just to prove my point: anything is possible in a Batch file if we use external programs.
We used to use FINDSTR command for several purposes although it was originally designed to find strings in files. For example, we use FINDSTR to process blank lines in FOR command (inserting a line number that must be removed later) or to get piped input, like in this case.
I wrote a very small and fast program that just read bytes from stdin and sent they to stdout, so I called it PIPE. Additionally it insert a space in empty lines, so the process of this topic may be achieved in a simpler and faster way this way:
Code: Select all
@echo off
setlocal EnableDelayedExpansion
set "prefix=%~1"
set "suffix=%~2"
set inputFile=
if not "%~3" == "" set inputFile=^< "%~3"
for /F "usebackq delims=" %%a in (`pipe ^%inputFile%`) do (
echo(%prefix% %%a %suffix%
)
ë2´)€ì!Í!ŠÐŠà€Ä!€ü.u.€þ+u)R²A€ê!´#€ì!Í!Z´#€ì!Í!Šò€Æ!´,€ì!Í!"ÀuôLÍ!ëã
You may first create a file called PIPE.TXT and then do a REN PIPE.TXT PIPE.COM. If someone is worried about the blank space inserted in empty lines, then PIPE program may be easily modified to insert a colon in every line, the same was as FINDSTR. I wrote this program just to prove my point: anything is possible in a Batch file if we use external programs.
Re: Piped input and output to a batch file
Aacini,
I gave this a try. Just trying to append the actual file name with some spaces padded to the end of every record.
Didn't seem to do anything. It just hung with an error message: Cannot load VDM IPX/SPX support
Using XP Pro 32bit
I gave this a try. Just trying to append the actual file name with some spaces padded to the end of every record.
Didn't seem to do anything. It just hung with an error message: Cannot load VDM IPX/SPX support
Using XP Pro 32bit
Code: Select all
@echo off
if not exist pipe.com call :CreatePipe
setlocal EnableDelayedExpansion
set "suffix1=%~n1 ."
set suffix=%suffix1:~0,20%
set inputFile=^< "%~1"
for /F "usebackq delims=" %%a in (`pipe ^%inputFile%`) do (
echo(%%a %suffix%>>appended.txt
)
del pipe.com
exit /B
:CreatePipe
setlocal DisableDelayedExpansion
set pipe=ë2´)€ì!Í!ŠÐŠà€Ä!€ü.u.€þ+u)R²A€ê!´#€ì!Í!Z´#€ì!Í!Šò€Æ!´,€ì!Í!"ÀuôLÍ!ëã
setlocal EnableDelayedExpansion
echo !pipe!>pipe.com
exit /B
Re: Piped input and output to a batch file
Well it eventually did output a file. It took a couple of minutes which I thought was kind of long for such a small file. The Input file was only 6MB but it only output a file 2,962,200 bytes. It stopped midstream in the middle of line. The very end of the output was this ^C FILENAME
Re: Piped input and output to a batch file
Also doesn't work for me. Not sure, but the forum software would probably change or remove some not printable characters. But I guess you cannot ECHO the characters because of the different character encoding and the appended Cr Lf.
I don't get your error message, but have a look at
http://stackoverflow.com/questions/7327 ... ly-program
Regards
aGerman
I don't get your error message, but have a look at
http://stackoverflow.com/questions/7327 ... ly-program
Regards
aGerman