W
Walter Briscoe
I am running an XP cmd.exe on a W2K system.
I have a script in which the output of one command is fed as an argument
to a second. My command is long and I have hidden some of the details in
foo.bat, bar.bat, and fubar.bat.
) type foo.bat
@echo foo.bat
:: Line in foo.bat containing the word pharlap
) type bar.bat
@echo bar.bat
:: Line in bar.bat containing the word pharlap
:: Does Microsoft have a command to copy standard input to standard output?
@cat
) type fubar.bat
@echo off
foo 2>nul | bar
) foo 2>nul | bar
bar.bat
foo.bat
) fubar
bar.bat
foo.bat
)
I surround long lines in chevron pairs ("<" and ">") to try to persuade
news readers not to split them.
My original command was:
<c:\cygwin\bin\bash.exe -c "grep -n -i -- 'pharlap' `wmake -h -n -d -a -f makefile 2> nul | sed '/^.*Entering file (\([^)]*\).*/!d;s//\1/'`">
The simplified command's operation is:
<) c:\cygwin\bin\bash.exe -c "echo `cmd /c foo 2>nul | cmd /c bar`">
bar.bat foo.bat
<) c:\cygwin\bin\bash.exe -c "grep -n -i -- pharlap `cmd /c foo 2>nul | cmd /c bar`">
bar.bat:2::: Line in bar.bat containing the word pharlap
foo.bat:2::: Line in foo.bat containing the word pharlap
)
Yesterday, I realized I could replace the dependency on bash with
another on xargs and came up with the slightly simpler command:
<wmake -h -n -d -a -f makefile 2>nul | sed "/^.*Entering file (\([^)]*\).*/!d;s//\1/;s:\\\:&&:g" | xargs grep -n -i pharlap>
This simplifies to the following:
) foo 2>nul | bar | xargs grep -n -i pharlap
bar.bat:2::: Line in bar.bat containing the word pharlap
foo.bat:2::: Line in foo.bat containing the word pharlap
)
So much for history! Because xargs is not available in my target
environment, I want to use the backtick or quoted-command facilities of
cmd.exe's for command. However, they seem to give higher priority to ">"
(redirection) and "|" (pipe) than "`" (backtick) and I have no
reasonable way to work around that.
They also produce output in many lines rather than one. I have a
workaround for that for my particular requirement.
) :: backtick and quote have lower priority than redirect and pipe
) for /F "usebackq" %c in (`foo 2>nul | bar`) do @rem
2> was unexpected at this time.
) for /F "usebackq" %c in (`foo | bar`) do @rem
| was unexpected at this time.
) for /F %c in ('foo 2>nul | bar') do @rem
2> was unexpected at this time.
) for /F %c in ('foo | bar') do @rem
| was unexpected at this time.
)
) :: I can use a wrapper batch, but do not want to.
) :: Even if I do, I can not force output onto one line
) for /F "usebackq" %c in (`fubar `) do @echo %c
bar.bat
foo.bat
) :: I think eol=? means ignore characters after ? in text lines
) for /F "usebackq eol=?" %c in (`fubar `) do @echo %c
bar.bat
foo.bat
) :: grep is called once for each file rather than once for all files
<) for /F "usebackq eol=?" %c in (`fubar `) do @grep -n -i -- pharlap %c>
2::: Line in bar.bat containing the word pharlap
2::: Line in foo.bat containing the word pharlap
) :: I can cheat to force grep to put names on its outputs
<) for /F "usebackq eol=?" %c in (`fubar `) do @grep -n -i -- pharlap %c nul>
bar.bat:2::: Line in bar.bat containing the word pharlap
foo.bat:2::: Line in foo.bat containing the word pharlap
) :: This is more economical in characters but aligned for comparison
<) for /F %c in ('fubar ') do @grep -n -i -- pharlap %c nul>
bar.bat:2::: Line in bar.bat containing the word pharlap
foo.bat:2::: Line in foo.bat containing the word pharlap
) :: This is the unaligned version
) for /F %c in ('fubar') do @grep -n -i -- pharlap %c nul
bar.bat:2::: Line in bar.bat containing the word pharlap
foo.bat:2::: Line in foo.bat containing the word pharlap
)
Can somebody please point out how I can do the following in a for
command or confirm my analysis that Microsoft does not yet allow for
them?
1) use ">" (redirection) and "|" (pipe)
2) force output onto a single line
I have a script in which the output of one command is fed as an argument
to a second. My command is long and I have hidden some of the details in
foo.bat, bar.bat, and fubar.bat.
) type foo.bat
@echo foo.bat
:: Line in foo.bat containing the word pharlap
) type bar.bat
@echo bar.bat
:: Line in bar.bat containing the word pharlap
:: Does Microsoft have a command to copy standard input to standard output?
@cat
) type fubar.bat
@echo off
foo 2>nul | bar
) foo 2>nul | bar
bar.bat
foo.bat
) fubar
bar.bat
foo.bat
)
I surround long lines in chevron pairs ("<" and ">") to try to persuade
news readers not to split them.
My original command was:
<c:\cygwin\bin\bash.exe -c "grep -n -i -- 'pharlap' `wmake -h -n -d -a -f makefile 2> nul | sed '/^.*Entering file (\([^)]*\).*/!d;s//\1/'`">
The simplified command's operation is:
<) c:\cygwin\bin\bash.exe -c "echo `cmd /c foo 2>nul | cmd /c bar`">
bar.bat foo.bat
<) c:\cygwin\bin\bash.exe -c "grep -n -i -- pharlap `cmd /c foo 2>nul | cmd /c bar`">
bar.bat:2::: Line in bar.bat containing the word pharlap
foo.bat:2::: Line in foo.bat containing the word pharlap
)
Yesterday, I realized I could replace the dependency on bash with
another on xargs and came up with the slightly simpler command:
<wmake -h -n -d -a -f makefile 2>nul | sed "/^.*Entering file (\([^)]*\).*/!d;s//\1/;s:\\\:&&:g" | xargs grep -n -i pharlap>
This simplifies to the following:
) foo 2>nul | bar | xargs grep -n -i pharlap
bar.bat:2::: Line in bar.bat containing the word pharlap
foo.bat:2::: Line in foo.bat containing the word pharlap
)
So much for history! Because xargs is not available in my target
environment, I want to use the backtick or quoted-command facilities of
cmd.exe's for command. However, they seem to give higher priority to ">"
(redirection) and "|" (pipe) than "`" (backtick) and I have no
reasonable way to work around that.
They also produce output in many lines rather than one. I have a
workaround for that for my particular requirement.
) :: backtick and quote have lower priority than redirect and pipe
) for /F "usebackq" %c in (`foo 2>nul | bar`) do @rem
2> was unexpected at this time.
) for /F "usebackq" %c in (`foo | bar`) do @rem
| was unexpected at this time.
) for /F %c in ('foo 2>nul | bar') do @rem
2> was unexpected at this time.
) for /F %c in ('foo | bar') do @rem
| was unexpected at this time.
)
) :: I can use a wrapper batch, but do not want to.
) :: Even if I do, I can not force output onto one line
) for /F "usebackq" %c in (`fubar `) do @echo %c
bar.bat
foo.bat
) :: I think eol=? means ignore characters after ? in text lines
) for /F "usebackq eol=?" %c in (`fubar `) do @echo %c
bar.bat
foo.bat
) :: grep is called once for each file rather than once for all files
<) for /F "usebackq eol=?" %c in (`fubar `) do @grep -n -i -- pharlap %c>
2::: Line in bar.bat containing the word pharlap
2::: Line in foo.bat containing the word pharlap
) :: I can cheat to force grep to put names on its outputs
<) for /F "usebackq eol=?" %c in (`fubar `) do @grep -n -i -- pharlap %c nul>
bar.bat:2::: Line in bar.bat containing the word pharlap
foo.bat:2::: Line in foo.bat containing the word pharlap
) :: This is more economical in characters but aligned for comparison
<) for /F %c in ('fubar ') do @grep -n -i -- pharlap %c nul>
bar.bat:2::: Line in bar.bat containing the word pharlap
foo.bat:2::: Line in foo.bat containing the word pharlap
) :: This is the unaligned version
) for /F %c in ('fubar') do @grep -n -i -- pharlap %c nul
bar.bat:2::: Line in bar.bat containing the word pharlap
foo.bat:2::: Line in foo.bat containing the word pharlap
)
Can somebody please point out how I can do the following in a for
command or confirm my analysis that Microsoft does not yet allow for
them?
1) use ">" (redirection) and "|" (pipe)
2) force output onto a single line