【问题标题】:Read stdin stream in a batch file在批处理文件中读取标准输入流
【发布时间】:2022-01-08 00:22:14
【问题描述】:

是否可以在批处理文件中使用管道标准输入流?

我希望能够将一个命令的输出重定向到我的批处理文件process.bat 列表中,所以:

C:\>someOtherProgram.exe | process.bat

我的第一次尝试是这样的:

echo OFF
setlocal

:again
set /p inputLine=""
echo.%inputLine%
if not (%inputLine%)==() goto again

endlocal
:End

当我使用type testFile.txt | process.bat 对其进行测试时,它会重复打印出第一行。

还有其他方法吗?

【问题讨论】:

  • 好问题,好答案,真的搞砸了,没有更好的答案!

标签: windows batch-file stdout stdin


【解决方案1】:

set /p 不适用于管道,它从输入中获取一行(随机)。
但是您可以在 for 循环中使用 more

@echo off
setlocal
for /F "tokens=*" %%a in ('more') do (
  echo #%%a
)

但这会失败,因为行以分号开头(因为 eol 的 FOR-LOOP 标准是 ;)。
而且它不能读取空行。
但是使用 findstr 你也可以解决这个问题,它在每一行前面加上行号,所以你永远不会得到空行。
然后前缀被删除到第一个冒号。

@echo off
setlocal DisableDelayedExpansion

for /F "tokens=*" %%a in ('findstr /n $') do (
  set "line=%%a"
  setlocal EnableDelayedExpansion
  set "line=!line:*:=!"
  echo(!line!
  endlocal
)

或者,在某些不包含findstr 的环境(如WinRE)上,使用find.exe 的替代方案可能就足够了。 find 将接受空搜索字符串"",并允许搜索反转。这将允许这样的事情:

@echo off
setlocal DisableDelayedExpansion

for /F "tokens=*" %%a in ('find /v ""') do (
  ...

【讨论】:

  • 这似乎有效。我以前没见过set "line=!line:*:=!" 语法。更多的批处理脚本疯狂。我已经稍微调整了它以使用 MSYS 工具; sed "s/^\(.*\)$/\"\1\"/"' 而不是 findstr /n $。然后可以用echo.%%~a 替换正文,它可以处理无dos 行结尾(我在很多文件中都有)。
  • 最好使用FINDSTR /N "^"。该搜索将正确返回所有行,包括 unix 格式的行以及可能不以换行符结尾的任何最后一行。
  • 我认为您可以使用for /F "tokens=* eol=" 来处理以分号开头的行。
  • 是的,它可以处理带分号的行,但随后它会因引号而失败,因为 EOL=" 不会为空 EOL
  • @bers 第三个示例不完整((这是 Dan 的编辑)。对于行长度和变量,批处理的硬性限制为 8191 个字符。
【解决方案2】:

设置“line=!line:*:=!”的语法是:

  1. 设置需要一个参数,即a=b
    如果 a 包含空格或其他内容,则必须在此参数周围使用引号。这里我没有看到任何

  2. !line:*:=!
    对于这种语法,你可以输入'set /?'来查看使用变量的官方说明。
    !var!类似于%var%,获取值。但!var! 表示延迟扩张

行变量名

第一个:变量修改标记。

**:= **:=(empty),将变量值中匹配“*:”的字符串(实际上从字符串开始到第一个:出现)替换为(空),即删除从开始到第一个冒号的子字符串.

【讨论】:

    【解决方案3】:
    FOR /F "tokens=1* delims=]" %%A IN ('FIND /N /V ""') DO (
        >  CON    ECHO.%%B
        >> %File% ECHO.%%B
    )
    

    来源:http://www.robvanderwoude.com/unixports.php#TEE

    【讨论】:

    • 这不会在以分号开头的行上失败。
    • 但对我来说,它在以] 开头的行上失败了。
    【解决方案4】:

    或者,在某些不包含findstr 的环境(如WinRE)上,使用find.exe 的替代方案可能就足够了。 find 将接受空搜索字符串"",并允许搜索反转。这将允许这样的事情:

    @echo off
    setlocal DisableDelayedExpansion
    
    for /F "tokens=*" %%a in ('find /v ""') do (
      set "line=%%a"
      echo(!line!
    )
    

    【讨论】:

    • !line! 当然不适用于DisableDelayedExpansion。此外,这不会打印空行。
    猜你喜欢
    • 1970-01-01
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 2013-03-18
    • 2011-03-30
    • 1970-01-01
    相关资源
    最近更新 更多