web-dev-qa-db-ja.com

バッチファイルでstdinストリームを読み取る

バッチファイル内でパイプされたstdinストリームを使用することは可能ですか?

1つのコマンドの出力をバッチファイル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でテストすると、最初の行が繰り返し出力されます。

別の方法はありますか?

35
m0tive

set /pはパイプでは機能せず、入力から(ランダムに)1行を取得します。
しかし、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はnull検索文字列""を受け入れ、検索の逆転を可能にします。これにより、次のようなことが可能になります。

@echo off
setlocal DisableDelayedExpansion

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

セット "line=!line:*:=! "の構文は次のとおりです。

  1. セットには、a=b
    aにスペースなどが含まれている場合は、このパラメーターを引用符で囲む必要があります。ここには何も見えません

  2. !line:*:=!
    この構文では、「set /? '変数の使用に関する公式の説明をご覧ください。
    !var! のようなものです %var%、値を取得します。だが !var!遅延展開を意味します。

ライン変数名

最初の変数変更マーク。

**:= **:=(空)、変数の値の文字列を「*: "(実質的に文字列の先頭から最初の:オカレンス)(空)で、つまり、開始から最初のコロンまでの部分文字列を削除します。

3
YumeYao
FOR /F "tokens=1* delims=]" %%A IN ('FIND /N /V ""') DO (
    >  CON    ECHO.%%B
    >> %File% ECHO.%%B
)

ここにソース: http://www.robvanderwoude.com/unixports.php#TEE

1
Amr Ali

または、findstrを含まない一部の環境(WinREなど)では、find.exeを使用した代替で十分な場合があります。 findはnull検索文字列""を受け入れ、検索の逆転を可能にします。これにより、次のようなことが可能になります。

@echo off
setlocal DisableDelayedExpansion

for /F "tokens=*" %%a in ('find /v ""') do (
  set "line=%%a"
  echo(!line!
)
0
Dan